mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-09 23:08:18 +02:00
brw: Remove old encoder, generator and related tools
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41413>
This commit is contained in:
parent
15e53be9c9
commit
181eaee52e
26 changed files with 84 additions and 22344 deletions
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "brw_asm.h"
|
||||
#include "brw_asm_internal.h"
|
||||
#include "brw_disasm_info.h"
|
||||
#include "util/hash_table.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int offset; /* -1 for unset */
|
||||
struct util_dynarray jip_uses;
|
||||
struct util_dynarray uip_uses;
|
||||
} brw_asm_label;
|
||||
|
||||
static brw_asm_label *
|
||||
brw_asm_label_lookup(struct brw_asm_parser *parser, const char *name)
|
||||
{
|
||||
uint32_t h = _mesa_hash_string(name);
|
||||
struct hash_entry *entry =
|
||||
_mesa_hash_table_search_pre_hashed(parser->labels, h, name);
|
||||
if (!entry) {
|
||||
void *mem_ctx = parser->labels;
|
||||
brw_asm_label *label = rzalloc(mem_ctx, brw_asm_label);
|
||||
label->name = ralloc_strdup(mem_ctx, name);
|
||||
label->offset = -1;
|
||||
util_dynarray_init(&label->jip_uses, mem_ctx);
|
||||
util_dynarray_init(&label->uip_uses, mem_ctx);
|
||||
entry = _mesa_hash_table_insert_pre_hashed(parser->labels,
|
||||
h, name, label);
|
||||
}
|
||||
assert(entry);
|
||||
return entry->data;
|
||||
}
|
||||
|
||||
void
|
||||
brw_asm_label_set(struct brw_asm_parser *parser, const char *name)
|
||||
{
|
||||
brw_asm_label *label = brw_asm_label_lookup(parser, name);
|
||||
label->offset = parser->p->next_insn_offset;
|
||||
}
|
||||
|
||||
void
|
||||
brw_asm_label_use_jip(struct brw_asm_parser *parser, const char *name)
|
||||
{
|
||||
struct brw_codegen *p = parser->p;
|
||||
brw_asm_label *label = brw_asm_label_lookup(parser, name);
|
||||
int offset = p->next_insn_offset - sizeof(brw_eu_inst);
|
||||
util_dynarray_append(&label->jip_uses, offset);
|
||||
/* Will be patched later. */
|
||||
brw_eu_inst_set_jip(p->devinfo, brw_last_inst, 0);
|
||||
}
|
||||
|
||||
void
|
||||
brw_asm_label_use_uip(struct brw_asm_parser *parser, const char *name)
|
||||
{
|
||||
struct brw_codegen *p = parser->p;
|
||||
brw_asm_label *label = brw_asm_label_lookup(parser, name);
|
||||
int offset = p->next_insn_offset - sizeof(brw_eu_inst);
|
||||
util_dynarray_append(&label->uip_uses, offset);
|
||||
/* Will be patched later. */
|
||||
brw_eu_inst_set_uip(p->devinfo, brw_last_inst, 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
brw_postprocess_labels(struct brw_asm_parser *parser)
|
||||
{
|
||||
unsigned unknown = 0;
|
||||
struct brw_codegen *p = parser->p;
|
||||
void *store = p->store;
|
||||
|
||||
hash_table_foreach(parser->labels, entry) {
|
||||
brw_asm_label *label = entry->data;
|
||||
|
||||
if (label->offset == -1) {
|
||||
fprintf(stderr, "Unknown label '%s'\n", label->name);
|
||||
unknown++;
|
||||
continue;
|
||||
}
|
||||
|
||||
util_dynarray_foreach(&label->jip_uses, int, use_offset) {
|
||||
brw_eu_inst *inst = store + *use_offset;
|
||||
brw_eu_inst_set_jip(parser->devinfo, inst, label->offset - *use_offset);
|
||||
}
|
||||
|
||||
util_dynarray_foreach(&label->uip_uses, int, use_offset) {
|
||||
brw_eu_inst *inst = store + *use_offset;
|
||||
brw_eu_inst_set_uip(parser->devinfo, inst, label->offset - *use_offset);
|
||||
}
|
||||
}
|
||||
|
||||
return unknown == 0;
|
||||
}
|
||||
|
||||
/* TODO: Would be nice to make this operate on string instead on a FILE. */
|
||||
|
||||
brw_assemble_result
|
||||
brw_assemble(void *mem_ctx, const struct intel_device_info *devinfo,
|
||||
FILE *f, const char *filename, brw_assemble_flags flags)
|
||||
{
|
||||
brw_assemble_result result = {0};
|
||||
|
||||
struct brw_isa_info isa;
|
||||
brw_init_isa_info(&isa, devinfo);
|
||||
|
||||
/* This is allocated separatedly from the parser since will outlive
|
||||
* the parser state.
|
||||
*/
|
||||
struct brw_codegen *p = rzalloc(mem_ctx, struct brw_codegen);
|
||||
brw_init_codegen(&isa, p, p);
|
||||
|
||||
brw_asm_parser *parser = rzalloc(mem_ctx, brw_asm_parser);
|
||||
parser->devinfo = devinfo;
|
||||
parser->labels = _mesa_string_hash_table_create(parser);
|
||||
parser->p = p;
|
||||
parser->input_filename = filename;
|
||||
parser->compaction_warning_given = false;
|
||||
|
||||
parser->scanner = NULL;
|
||||
brw_asm_lex_init_extra(parser, &parser->scanner);
|
||||
brw_asm_restart(f, parser->scanner);
|
||||
|
||||
int err = yyparse(parser);
|
||||
brw_asm_lex_destroy(parser->scanner);
|
||||
if (err || parser->errors)
|
||||
goto end;
|
||||
|
||||
if (!brw_postprocess_labels(parser))
|
||||
goto end;
|
||||
|
||||
struct disasm_info *disasm_info = disasm_initialize(p->isa, NULL);
|
||||
if (!disasm_info) {
|
||||
ralloc_free(disasm_info);
|
||||
fprintf(stderr, "Unable to initialize disasm_info struct instance\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Add "inst groups" so validation errors can be recorded. */
|
||||
for (int i = 0; i <= p->next_insn_offset; i += 16)
|
||||
disasm_new_inst_group(disasm_info, i);
|
||||
|
||||
if (!brw_validate_instructions(p->isa, p->store, 0,
|
||||
p->next_insn_offset, disasm_info)) {
|
||||
dump_assembly(p->store, 0, p->next_insn_offset, disasm_info, NULL, stderr);
|
||||
ralloc_free(disasm_info);
|
||||
fprintf(stderr, "Invalid instructions.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((flags & BRW_ASSEMBLE_COMPACT) != 0)
|
||||
brw_compact_instructions(p, 0, disasm_info);
|
||||
|
||||
result.bin = p->store;
|
||||
result.bin_size = p->next_insn_offset;
|
||||
|
||||
if ((flags & BRW_ASSEMBLE_DUMP) != 0)
|
||||
dump_assembly(p->store, 0, p->next_insn_offset, disasm_info, NULL, stderr);
|
||||
|
||||
ralloc_free(disasm_info);
|
||||
|
||||
end:
|
||||
ralloc_free(parser);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct intel_device_info;
|
||||
|
||||
typedef struct {
|
||||
void *bin;
|
||||
int bin_size;
|
||||
} brw_assemble_result;
|
||||
|
||||
typedef enum {
|
||||
BRW_ASSEMBLE_COMPACT = 1 << 0,
|
||||
BRW_ASSEMBLE_DUMP = 1 << 1,
|
||||
} brw_assemble_flags;
|
||||
|
||||
brw_assemble_result brw_assemble(
|
||||
void *mem_ctx, const struct intel_device_info *devinfo,
|
||||
FILE *f, const char *filename, brw_assemble_flags flags);
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Assembler internal state and definitions used by the brw_gram/brw_lex. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "brw_eu.h"
|
||||
#include "brw_eu_defines.h"
|
||||
#include "brw_eu_inst.h"
|
||||
#include "brw_reg.h"
|
||||
#include "brw_reg_type.h"
|
||||
#include "dev/intel_device_info.h"
|
||||
#include "util/list.h"
|
||||
|
||||
/* glibc < 2.27 defines OVERFLOW in /usr/include/math.h. */
|
||||
#undef OVERFLOW
|
||||
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void *yyscan_t;
|
||||
#endif
|
||||
|
||||
typedef struct brw_asm_parser {
|
||||
const struct intel_device_info *devinfo;
|
||||
struct brw_codegen *p;
|
||||
const char *input_filename;
|
||||
int errors;
|
||||
bool compaction_warning_given;
|
||||
struct hash_table *labels;
|
||||
|
||||
/* Lexer state. */
|
||||
yyscan_t scanner;
|
||||
int saved_state;
|
||||
} brw_asm_parser;
|
||||
|
||||
/* A helper for accessing the last instruction emitted. This makes it easy
|
||||
* to set various bits on an instruction without having to create temporary
|
||||
* variable and assign the emitted instruction to those.
|
||||
*/
|
||||
#define brw_last_inst brw_eu_last_inst(parser->p)
|
||||
|
||||
int yyparse(struct brw_asm_parser *parser);
|
||||
char *brw_asm_get_text(yyscan_t scanner);
|
||||
|
||||
int brw_asm_lex_init_extra(struct brw_asm_parser *parser, yyscan_t *scanner);
|
||||
int brw_asm_lex_destroy(yyscan_t scanner);
|
||||
void brw_asm_restart(FILE *input_file, yyscan_t scanner);
|
||||
|
||||
struct condition {
|
||||
unsigned cond_modifier:4;
|
||||
unsigned flag_reg_nr:1;
|
||||
unsigned flag_subreg_nr:1;
|
||||
};
|
||||
|
||||
struct predicate {
|
||||
unsigned pred_control:4;
|
||||
unsigned pred_inv:1;
|
||||
unsigned flag_reg_nr:1;
|
||||
unsigned flag_subreg_nr:1;
|
||||
};
|
||||
|
||||
enum instoption_type {
|
||||
INSTOPTION_FLAG,
|
||||
INSTOPTION_DEP_INFO,
|
||||
INSTOPTION_CHAN_OFFSET,
|
||||
};
|
||||
|
||||
struct instoption {
|
||||
enum instoption_type type;
|
||||
union {
|
||||
unsigned uint_value;
|
||||
gen_swsb depinfo_value;
|
||||
};
|
||||
};
|
||||
|
||||
struct options {
|
||||
uint8_t chan_offset;
|
||||
unsigned access_mode:1;
|
||||
unsigned compression_control:2;
|
||||
unsigned thread_control:2;
|
||||
unsigned branch_control:1;
|
||||
unsigned no_dd_check:1; // Dependency control
|
||||
unsigned no_dd_clear:1; // Dependency control
|
||||
unsigned mask_control:1;
|
||||
unsigned debug_control:1;
|
||||
unsigned acc_wr_control:1;
|
||||
unsigned end_of_thread:1;
|
||||
unsigned compaction:1;
|
||||
unsigned is_compr:1;
|
||||
gen_swsb depinfo;
|
||||
};
|
||||
|
||||
struct msgdesc {
|
||||
unsigned ex_bso:1;
|
||||
unsigned src1_len:5;
|
||||
};
|
||||
|
||||
void brw_asm_label_set(struct brw_asm_parser *parser, const char *name);
|
||||
void brw_asm_label_use_jip(struct brw_asm_parser *parser, const char *name);
|
||||
void brw_asm_label_use_uip(struct brw_asm_parser *parser, const char *name);
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "util/ralloc.h"
|
||||
#include "brw_eu_inst.h"
|
||||
#include "dev/intel_device_info.h"
|
||||
|
||||
#include "brw_asm.h"
|
||||
|
||||
enum opt_output_type {
|
||||
OPT_OUTPUT_HEX,
|
||||
OPT_OUTPUT_C_LITERAL,
|
||||
OPT_OUTPUT_BIN,
|
||||
};
|
||||
|
||||
static enum opt_output_type output_type = OPT_OUTPUT_BIN;
|
||||
|
||||
static void
|
||||
print_help(const char *progname, FILE *file)
|
||||
{
|
||||
fprintf(file,
|
||||
"Usage: %s [OPTION] inputfile\n"
|
||||
"Assemble i965 instructions from input file.\n\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -t, --type=OUTPUT_TYPE OUTPUT_TYPE can be 'bin' (default if omitted),\n"
|
||||
" 'c_literal', or 'hex'\n"
|
||||
" -o, --output specify output file\n"
|
||||
" --compact print compacted instructions\n"
|
||||
" -g, --gen=platform assemble instructions for given \n"
|
||||
" platform (3 letter platform name)\n"
|
||||
"Example:\n"
|
||||
" brw_asm -g kbl input.asm -t hex -o output\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_dword(const brw_eu_inst *inst, int idx)
|
||||
{
|
||||
uint32_t dword;
|
||||
memcpy(&dword, (char *)inst + 4 * idx, sizeof(dword));
|
||||
return dword;
|
||||
}
|
||||
|
||||
static void
|
||||
print_instruction(FILE *output, bool compact, const brw_eu_inst *instruction)
|
||||
{
|
||||
int byte_limit;
|
||||
|
||||
byte_limit = (compact == true) ? 8 : 16;
|
||||
|
||||
switch (output_type) {
|
||||
case OPT_OUTPUT_HEX: {
|
||||
fprintf(output, "%02x", ((unsigned char *)instruction)[0]);
|
||||
|
||||
for (unsigned i = 1; i < byte_limit; i++) {
|
||||
fprintf(output, " %02x", ((unsigned char *)instruction)[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OPT_OUTPUT_C_LITERAL: {
|
||||
fprintf(output, "\t0x%08x,", get_dword(instruction, 0));
|
||||
|
||||
for (unsigned i = 1; i < byte_limit / 4; i++)
|
||||
fprintf(output, " 0x%08x,", get_dword(instruction, i));
|
||||
|
||||
break;
|
||||
}
|
||||
case OPT_OUTPUT_BIN:
|
||||
fwrite(instruction, 1, byte_limit, output);
|
||||
break;
|
||||
}
|
||||
|
||||
if (output_type != OPT_OUTPUT_BIN) {
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static struct intel_device_info *
|
||||
i965_asm_init(uint16_t pci_id)
|
||||
{
|
||||
struct intel_device_info *devinfo;
|
||||
|
||||
devinfo = malloc(sizeof *devinfo);
|
||||
if (devinfo == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!intel_get_device_info_from_pci_id(pci_id, devinfo)) {
|
||||
fprintf(stderr, "can't find device information: pci_id=0x%x\n",
|
||||
pci_id);
|
||||
free(devinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (devinfo->ver < 9) {
|
||||
fprintf(stderr, "device has gfx version %d but must be >= 9, try elk_asm instead",
|
||||
devinfo->ver);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return devinfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
void *mem_ctx = ralloc_context(NULL);
|
||||
FILE *input_file = NULL;
|
||||
char *output_file = NULL;
|
||||
int c;
|
||||
FILE *output = stdout;
|
||||
bool help = false, compact = false;
|
||||
uint64_t pci_id = 0;
|
||||
struct intel_device_info *devinfo = NULL;
|
||||
int result = EXIT_FAILURE;
|
||||
|
||||
const struct option brw_asm_opts[] = {
|
||||
{ "help", no_argument, (int *) &help, true },
|
||||
{ "type", required_argument, NULL, 't' },
|
||||
{ "gen", required_argument, NULL, 'g' },
|
||||
{ "output", required_argument, NULL, 'o' },
|
||||
{ "compact", no_argument, (int *) &compact, true },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, ":t:g:o:h", brw_asm_opts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'g': {
|
||||
const int id = intel_device_name_to_pci_device_id(optarg);
|
||||
if (id < 0) {
|
||||
fprintf(stderr, "can't parse gen: '%s', expected 3 letter "
|
||||
"platform name\n", optarg);
|
||||
goto end;
|
||||
} else {
|
||||
pci_id = id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
help = true;
|
||||
print_help(argv[0], stderr);
|
||||
goto end;
|
||||
case 't': {
|
||||
if (strcmp(optarg, "hex") == 0) {
|
||||
output_type = OPT_OUTPUT_HEX;
|
||||
} else if (strcmp(optarg, "c_literal") == 0) {
|
||||
output_type = OPT_OUTPUT_C_LITERAL;
|
||||
} else if (strcmp(optarg, "bin") == 0) {
|
||||
output_type = OPT_OUTPUT_BIN;
|
||||
} else {
|
||||
fprintf(stderr, "invalid value for --type: %s\n", optarg);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'o':
|
||||
output_file = strdup(optarg);
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
case ':':
|
||||
fprintf(stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], optopt);
|
||||
goto end;
|
||||
case '?':
|
||||
default:
|
||||
fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",
|
||||
argv[0], optopt);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (help || !pci_id) {
|
||||
print_help(argv[0], stderr);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
fprintf(stderr, "Please specify input file\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
const char *filename = argv[optind];
|
||||
input_file = fopen(filename, "r");
|
||||
if (!input_file) {
|
||||
fprintf(stderr, "Unable to read input file : %s\n",
|
||||
filename);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (output_file) {
|
||||
output = fopen(output_file, "w");
|
||||
if (!output) {
|
||||
fprintf(stderr, "Couldn't open output file\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
devinfo = i965_asm_init(pci_id);
|
||||
if (!devinfo) {
|
||||
fprintf(stderr, "Unable to allocate memory for "
|
||||
"intel_device_info struct instance.\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
brw_assemble_result r = brw_assemble(mem_ctx, devinfo, input_file, filename,
|
||||
compact ? BRW_ASSEMBLE_COMPACT : 0);
|
||||
if (!r.bin)
|
||||
goto end;
|
||||
|
||||
if (output_type == OPT_OUTPUT_C_LITERAL)
|
||||
fprintf(output, "{\n");
|
||||
|
||||
for (int offset = 0; offset < r.bin_size;) {
|
||||
const brw_eu_inst *insn = r.bin + offset;
|
||||
bool compacted = false;
|
||||
|
||||
if (compact && brw_eu_inst_cmpt_control(devinfo, insn)) {
|
||||
offset += 8;
|
||||
compacted = true;
|
||||
} else {
|
||||
offset += 16;
|
||||
}
|
||||
|
||||
print_instruction(output, compacted, insn);
|
||||
}
|
||||
|
||||
if (output_type == OPT_OUTPUT_C_LITERAL)
|
||||
fprintf(output, "}");
|
||||
|
||||
result = EXIT_SUCCESS;
|
||||
goto end;
|
||||
|
||||
end:
|
||||
free(output_file);
|
||||
|
||||
if (input_file)
|
||||
fclose(input_file);
|
||||
|
||||
if (output)
|
||||
fclose(output);
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
|
||||
free(devinfo);
|
||||
|
||||
exit(result);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2024 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct brw_isa_info;
|
||||
struct brw_eu_inst;
|
||||
|
||||
const struct brw_label *brw_find_label(const struct brw_label *root, int offset);
|
||||
void brw_create_label(struct brw_label **labels, int offset, void *mem_ctx);
|
||||
int brw_disassemble_inst(FILE *file, const struct brw_isa_info *isa,
|
||||
const struct brw_eu_inst *inst, bool is_compacted,
|
||||
int offset, const struct brw_label *root_label);
|
||||
const struct
|
||||
brw_label *brw_label_assembly(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start, int end,
|
||||
void *mem_ctx);
|
||||
void brw_disassemble_with_labels(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start, int end, FILE *out);
|
||||
void brw_disassemble(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start, int end,
|
||||
const struct brw_label *root_label,
|
||||
int64_t *lineno_offset, FILE *out);
|
||||
int brw_disassemble_find_end(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start);
|
||||
void brw_disassemble_with_errors(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start,
|
||||
int64_t *lineno_offset, FILE *out);
|
||||
void brw_disassemble_with_lineno(const struct brw_isa_info *isa, uint32_t stage,
|
||||
int dispatch_width, uint32_t src_hash,
|
||||
const void *assembly, int start,
|
||||
int64_t lineno_offset, FILE *out);
|
||||
|
||||
const char *brw_lsc_op_to_string(unsigned op);
|
||||
const char *brw_lsc_addr_surftype_to_string(unsigned t);
|
||||
const char *brw_lsc_data_size_to_string(unsigned s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "brw_cfg.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_disasm.h"
|
||||
#include "brw_disasm_info.h"
|
||||
#include "dev/intel_debug.h"
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "util/lut.h"
|
||||
|
||||
static bool
|
||||
is_do_block(struct bblock_t *block)
|
||||
{
|
||||
return block->start()->opcode == BRW_OPCODE_DO;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_flow_block(struct bblock_t *block)
|
||||
{
|
||||
return block->start()->opcode == SHADER_OPCODE_FLOW;
|
||||
}
|
||||
|
||||
static bool
|
||||
should_omit_link(struct bblock_t *block,
|
||||
struct bblock_link *link)
|
||||
{
|
||||
return link->kind == bblock_link_physical &&
|
||||
(is_do_block(block) || is_do_block(link->block));
|
||||
}
|
||||
|
||||
static void
|
||||
print_successors_for_disasm(FILE *f, struct bblock_t *block)
|
||||
{
|
||||
brw_foreach_list_typed(struct bblock_link, succ, link,
|
||||
&block->children) {
|
||||
if (should_omit_link(block, succ))
|
||||
continue;
|
||||
if (is_do_block(succ->block) || is_flow_block(succ->block))
|
||||
print_successors_for_disasm(f, succ->block);
|
||||
else
|
||||
fprintf(f, " ->B%d", succ->block->num);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_predecessors_for_disasm(FILE *f, struct bblock_t *block)
|
||||
{
|
||||
brw_foreach_list_typed(struct bblock_link, pred, link,
|
||||
&block->parents) {
|
||||
if (should_omit_link(block, pred))
|
||||
continue;
|
||||
if (is_do_block(pred->block) || is_flow_block(pred->block))
|
||||
print_predecessors_for_disasm(f, pred->block);
|
||||
else
|
||||
fprintf(f, " <-B%d", pred->block->num);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dump_assembly(void *assembly, int start_offset, int end_offset,
|
||||
struct disasm_info *disasm, const unsigned *block_latency, FILE *f)
|
||||
{
|
||||
const struct brw_isa_info *isa = disasm->isa;
|
||||
const char *last_annotation_string = NULL;
|
||||
|
||||
void *mem_ctx = ralloc_context(NULL);
|
||||
const struct brw_label *root_label =
|
||||
brw_label_assembly(isa, assembly, start_offset, end_offset, mem_ctx);
|
||||
|
||||
brw_foreach_list_typed(struct inst_group, group, link, &disasm->group_list) {
|
||||
struct brw_exec_node *next_node = brw_exec_node_get_next(&group->link);
|
||||
if (brw_exec_node_is_tail_sentinel(next_node))
|
||||
break;
|
||||
|
||||
struct inst_group *next =
|
||||
brw_exec_node_data(struct inst_group, next_node, link);
|
||||
|
||||
int start_offset = group->offset;
|
||||
int end_offset = next->offset;
|
||||
|
||||
if (group->block_start) {
|
||||
fprintf(f, " START B%d", group->block_start->num);
|
||||
print_predecessors_for_disasm(f, group->block_start);
|
||||
if (block_latency)
|
||||
fprintf(f, " (%u cycles)",
|
||||
block_latency[group->block_start->num]);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
if (last_annotation_string != group->annotation) {
|
||||
last_annotation_string = group->annotation;
|
||||
if (last_annotation_string)
|
||||
fprintf(f, " %s\n", last_annotation_string);
|
||||
}
|
||||
|
||||
brw_disassemble(isa, assembly, start_offset, end_offset,
|
||||
root_label, NULL, f);
|
||||
|
||||
if (group->error) {
|
||||
fputs(group->error, f);
|
||||
}
|
||||
|
||||
if (group->block_end) {
|
||||
fprintf(f, " END B%d", group->block_end->num);
|
||||
print_successors_for_disasm(f, group->block_end);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
struct disasm_info *
|
||||
disasm_initialize(const struct brw_isa_info *isa,
|
||||
const struct cfg_t *cfg)
|
||||
{
|
||||
struct disasm_info *disasm = ralloc(NULL, struct disasm_info);
|
||||
brw_exec_list_make_empty(&disasm->group_list);
|
||||
disasm->isa = isa;
|
||||
disasm->cfg = cfg;
|
||||
disasm->cur_block = 0;
|
||||
disasm->use_tail = false;
|
||||
return disasm;
|
||||
}
|
||||
|
||||
struct inst_group *
|
||||
disasm_new_inst_group(struct disasm_info *disasm, int next_inst_offset)
|
||||
{
|
||||
assert(next_inst_offset >= 0);
|
||||
struct inst_group *tail = rzalloc(disasm, struct inst_group);
|
||||
tail->offset = next_inst_offset;
|
||||
brw_exec_list_push_tail(&disasm->group_list, &tail->link);
|
||||
return tail;
|
||||
}
|
||||
|
||||
void
|
||||
disasm_annotate(struct disasm_info *disasm,
|
||||
brw_inst *inst, int offset)
|
||||
{
|
||||
const struct cfg_t *cfg = disasm->cfg;
|
||||
|
||||
struct inst_group *group;
|
||||
if (!disasm->use_tail) {
|
||||
group = disasm_new_inst_group(disasm, offset);
|
||||
} else {
|
||||
disasm->use_tail = false;
|
||||
group = brw_exec_node_data(struct inst_group,
|
||||
brw_exec_list_get_tail_raw(&disasm->group_list), link);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (INTEL_DEBUG(DEBUG_ANNOTATION)) {
|
||||
group->annotation = inst->annotation;
|
||||
|
||||
if (group->annotation == NULL && inst->opcode == BRW_OPCODE_BFN)
|
||||
group->annotation = util_lut3_to_str[inst->src[3].ud & 0xff];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (inst->opcode == BRW_OPCODE_DO ||
|
||||
inst->opcode == SHADER_OPCODE_FLOW) {
|
||||
disasm->use_tail = true;
|
||||
disasm->cur_block++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cfg->blocks[disasm->cur_block]->start() == inst) {
|
||||
group->block_start = cfg->blocks[disasm->cur_block];
|
||||
}
|
||||
|
||||
if (cfg->blocks[disasm->cur_block]->end() == inst) {
|
||||
group->block_end = cfg->blocks[disasm->cur_block];
|
||||
disasm->cur_block++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
disasm_insert_error(struct disasm_info *disasm, int offset,
|
||||
int inst_size, const char *error)
|
||||
{
|
||||
brw_foreach_list_typed(struct inst_group, cur, link, &disasm->group_list) {
|
||||
struct brw_exec_node *next_node = brw_exec_node_get_next(&cur->link);
|
||||
if (brw_exec_node_is_tail_sentinel(next_node))
|
||||
break;
|
||||
|
||||
struct inst_group *next =
|
||||
brw_exec_node_data(struct inst_group, next_node, link);
|
||||
|
||||
if (next->offset <= offset)
|
||||
continue;
|
||||
|
||||
if (offset + inst_size != next->offset) {
|
||||
struct inst_group *new_group = ralloc(disasm, struct inst_group);
|
||||
memcpy(new_group, cur, sizeof(struct inst_group));
|
||||
|
||||
cur->error = NULL;
|
||||
cur->error_length = 0;
|
||||
cur->block_end = NULL;
|
||||
|
||||
new_group->offset = offset + inst_size;
|
||||
new_group->block_start = NULL;
|
||||
|
||||
brw_exec_node_insert_after(&cur->link, &new_group->link);
|
||||
}
|
||||
|
||||
if (cur->error)
|
||||
ralloc_strcat(&cur->error, error);
|
||||
else
|
||||
cur->error = ralloc_strdup(disasm, error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2014 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "compiler/brw_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct cfg_t;
|
||||
struct brw_inst;
|
||||
struct intel_device_info;
|
||||
|
||||
struct inst_group {
|
||||
struct brw_exec_node link;
|
||||
|
||||
int offset;
|
||||
|
||||
size_t error_length;
|
||||
char *error;
|
||||
|
||||
/* Pointers to the basic block in the CFG if the instruction group starts
|
||||
* or ends a basic block.
|
||||
*/
|
||||
struct bblock_t *block_start;
|
||||
struct bblock_t *block_end;
|
||||
|
||||
/* Annotation for the generated IR. */
|
||||
const char *annotation;
|
||||
};
|
||||
|
||||
struct disasm_info {
|
||||
struct brw_exec_list group_list;
|
||||
|
||||
const struct brw_isa_info *isa;
|
||||
const struct cfg_t *cfg;
|
||||
|
||||
/** Block index in the cfg. */
|
||||
int cur_block;
|
||||
bool use_tail;
|
||||
};
|
||||
|
||||
void
|
||||
dump_assembly(void *assembly, int start_offset, int end_offset,
|
||||
struct disasm_info *disasm, const unsigned *block_latency, FILE *f);
|
||||
|
||||
struct disasm_info *
|
||||
disasm_initialize(const struct brw_isa_info *isa,
|
||||
const struct cfg_t *cfg);
|
||||
|
||||
struct inst_group *
|
||||
disasm_new_inst_group(struct disasm_info *disasm, int offset);
|
||||
|
||||
void
|
||||
disasm_annotate(struct disasm_info *disasm,
|
||||
struct brw_inst *inst, int offset);
|
||||
|
||||
void
|
||||
disasm_insert_error(struct disasm_info *disasm, int offset,
|
||||
int inst_size, const char *error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "brw_disasm.h"
|
||||
#include "brw_isa_info.h"
|
||||
#include "dev/intel_device_info.h"
|
||||
#include "util/u_dynarray.h"
|
||||
|
||||
enum opt_input_type {
|
||||
OPT_INPUT_BINARY,
|
||||
OPT_INPUT_C_LITERAL,
|
||||
};
|
||||
|
||||
static enum opt_input_type input_type = OPT_INPUT_BINARY;
|
||||
|
||||
/* Return size of file in bytes pointed by fp */
|
||||
static long
|
||||
i965_disasm_get_file_size(FILE *fp)
|
||||
{
|
||||
long size;
|
||||
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Read hex file which should be in following format:
|
||||
* for example :
|
||||
* { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
|
||||
*/
|
||||
static void *
|
||||
i965_disasm_read_c_literal_file(FILE *fp, size_t *end)
|
||||
{
|
||||
struct util_dynarray assembly = {};
|
||||
uint32_t temp[2];
|
||||
|
||||
if (fscanf(fp, " { ") == EOF) {
|
||||
fprintf(stderr, "Couldn't find opening `{`\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fscanf(fp, "0x%x , 0x%x", &temp[0], &temp[1]) == 2) {
|
||||
util_dynarray_append(&assembly, temp[0]);
|
||||
util_dynarray_append(&assembly, temp[1]);
|
||||
} else {
|
||||
fprintf(stderr, "Couldn't read hex values\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (fscanf(fp, " , 0x%x , 0x%x ", &temp[0], &temp[1]) == 2) {
|
||||
util_dynarray_append(&assembly, temp[0]);
|
||||
util_dynarray_append(&assembly, temp[1]);
|
||||
}
|
||||
|
||||
if (fscanf(fp, "}") == EOF) {
|
||||
fprintf(stderr, "Couldn't find closing `}`\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*end = assembly.size;
|
||||
return assembly.data;
|
||||
}
|
||||
|
||||
static void *
|
||||
i965_disasm_read_binary(FILE *fp, size_t *end)
|
||||
{
|
||||
size_t size;
|
||||
void *assembly;
|
||||
|
||||
long sz = i965_disasm_get_file_size(fp);
|
||||
if (sz < 0)
|
||||
return NULL;
|
||||
|
||||
*end = (size_t)sz;
|
||||
if (!*end)
|
||||
return NULL;
|
||||
|
||||
assembly = malloc(*end + 1);
|
||||
if (assembly == NULL)
|
||||
return NULL;
|
||||
|
||||
size = fread(assembly, *end, 1, fp);
|
||||
if (!size) {
|
||||
free(assembly);
|
||||
return NULL;
|
||||
}
|
||||
return assembly;
|
||||
}
|
||||
|
||||
static void
|
||||
print_help(const char *progname, FILE *file)
|
||||
{
|
||||
fprintf(file,
|
||||
"Usage: %s [OPTION]...\n"
|
||||
"Disassemble i965 instructions from binary file.\n\n"
|
||||
" --help display this help and exit\n"
|
||||
" --input-path=PATH read binary file from binary file PATH\n"
|
||||
" --type=INPUT_TYPE INPUT_TYPE can be 'bin' (default if omitted),\n"
|
||||
" 'c_literal'.\n"
|
||||
" --gen=platform disassemble instructions for given \n"
|
||||
" platform (3 letter platform name)\n",
|
||||
progname);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
void *assembly = NULL;
|
||||
char *file_path = NULL;
|
||||
size_t start = 0, end = 0;
|
||||
uint16_t pci_id = 0;
|
||||
int c;
|
||||
int result = EXIT_FAILURE;
|
||||
|
||||
bool help = false;
|
||||
const struct option i965_disasm_opts[] = {
|
||||
{ "help", no_argument, (int *) &help, true },
|
||||
{ "input-path", required_argument, NULL, 'i' },
|
||||
{ "type", required_argument, NULL, 't' },
|
||||
{ "gen", required_argument, NULL, 'g'},
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((c = getopt_long(argc, argv, ":i:t:g:h", i965_disasm_opts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'g': {
|
||||
const int id = intel_device_name_to_pci_device_id(optarg);
|
||||
if (id < 0) {
|
||||
fprintf(stderr, "can't parse gen: '%s', expected 3 letter "
|
||||
"platform name\n", optarg);
|
||||
goto end;
|
||||
} else {
|
||||
pci_id = id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
file_path = strdup(optarg);
|
||||
fp = fopen(file_path, "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Unable to read input file : %s\n",
|
||||
file_path);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case 't':
|
||||
if (strcmp(optarg, "c_literal") == 0) {
|
||||
input_type = OPT_INPUT_C_LITERAL;
|
||||
} else if (strcmp(optarg, "bin") == 0) {
|
||||
input_type = OPT_INPUT_BINARY;
|
||||
} else {
|
||||
fprintf(stderr, "invalid value for --type: %s\n", optarg);
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
help = true;
|
||||
print_help(argv[0], stderr);
|
||||
goto end;
|
||||
case 0:
|
||||
break;
|
||||
case ':':
|
||||
fprintf(stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], optopt);
|
||||
goto end;
|
||||
case '?':
|
||||
default:
|
||||
fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",
|
||||
argv[0], optopt);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (help || !file_path || !pci_id) {
|
||||
print_help(argv[0], stderr);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
struct intel_device_info devinfo;
|
||||
if (!intel_get_device_info_from_pci_id(pci_id, &devinfo)) {
|
||||
fprintf(stderr, "can't find device information: pci_id=0x%x\n", pci_id);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (devinfo.ver < 9) {
|
||||
fprintf(stderr, "device has gfx version %d but must be >= 9, try elk_disasm instead",
|
||||
devinfo.ver);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct brw_isa_info isa;
|
||||
brw_init_isa_info(&isa, &devinfo);
|
||||
|
||||
if (input_type == OPT_INPUT_BINARY)
|
||||
assembly = i965_disasm_read_binary(fp, &end);
|
||||
else if (input_type == OPT_INPUT_C_LITERAL)
|
||||
assembly = i965_disasm_read_c_literal_file(fp, &end);
|
||||
|
||||
if (!assembly) {
|
||||
if (end)
|
||||
fprintf(stderr, "Unable to allocate buffer to read input file\n");
|
||||
else
|
||||
fprintf(stderr, "Failed to read input file\n");
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Disassemble i965 instructions from buffer assembly */
|
||||
brw_disassemble_with_labels(&isa, assembly, start, end, stdout);
|
||||
|
||||
result = EXIT_SUCCESS;
|
||||
|
||||
end:
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
|
||||
free(file_path);
|
||||
free(assembly);
|
||||
|
||||
exit(result);
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "brw_disasm.h"
|
||||
#include "brw_eu_defines.h"
|
||||
#include "brw_eu.h"
|
||||
#include "brw_private.h"
|
||||
|
|
@ -109,171 +108,6 @@ brw_swizzle_immediate(enum brw_reg_type type, uint32_t x, unsigned swz)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
brw_get_default_exec_size(struct brw_codegen *p)
|
||||
{
|
||||
return p->current->exec_size;
|
||||
}
|
||||
|
||||
unsigned
|
||||
brw_get_default_group(struct brw_codegen *p)
|
||||
{
|
||||
return p->current->group;
|
||||
}
|
||||
|
||||
unsigned
|
||||
brw_get_default_access_mode(struct brw_codegen *p)
|
||||
{
|
||||
return p->current->access_mode;
|
||||
}
|
||||
|
||||
gen_swsb
|
||||
brw_get_default_swsb(struct brw_codegen *p)
|
||||
{
|
||||
return p->current->swsb;
|
||||
}
|
||||
|
||||
void
|
||||
brw_set_default_exec_size(struct brw_codegen *p, unsigned value)
|
||||
{
|
||||
p->current->exec_size = value;
|
||||
}
|
||||
|
||||
void brw_set_default_predicate_control(struct brw_codegen *p, enum brw_predicate pc)
|
||||
{
|
||||
p->current->predicate = pc;
|
||||
}
|
||||
|
||||
void brw_set_default_predicate_inverse(struct brw_codegen *p, bool predicate_inverse)
|
||||
{
|
||||
p->current->pred_inv = predicate_inverse;
|
||||
}
|
||||
|
||||
void brw_set_default_flag_reg(struct brw_codegen *p, int reg, int subreg)
|
||||
{
|
||||
assert(subreg < 2);
|
||||
p->current->flag_subreg = reg * 2 + subreg;
|
||||
}
|
||||
|
||||
void brw_set_default_access_mode( struct brw_codegen *p, unsigned access_mode )
|
||||
{
|
||||
p->current->access_mode = access_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the range of channel enable signals given by
|
||||
* [group, group + exec_size) to the instruction passed as argument.
|
||||
*/
|
||||
void
|
||||
brw_eu_inst_set_group(const struct intel_device_info *devinfo,
|
||||
brw_eu_inst *inst, unsigned group)
|
||||
{
|
||||
if (devinfo->ver >= 20) {
|
||||
assert(group % 8 == 0 && group < 32);
|
||||
brw_eu_inst_set_qtr_control(devinfo, inst, group / 8);
|
||||
|
||||
} else {
|
||||
assert(group % 4 == 0 && group < 32);
|
||||
brw_eu_inst_set_qtr_control(devinfo, inst, group / 8);
|
||||
brw_eu_inst_set_nib_control(devinfo, inst, (group / 4) % 2);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brw_set_default_group(struct brw_codegen *p, unsigned group)
|
||||
{
|
||||
p->current->group = group;
|
||||
}
|
||||
|
||||
void brw_set_default_mask_control( struct brw_codegen *p, unsigned value )
|
||||
{
|
||||
p->current->mask_control = value;
|
||||
}
|
||||
|
||||
void brw_set_default_saturate( struct brw_codegen *p, bool enable )
|
||||
{
|
||||
p->current->saturate = enable;
|
||||
}
|
||||
|
||||
void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value)
|
||||
{
|
||||
p->current->acc_wr_control = value;
|
||||
}
|
||||
|
||||
void brw_set_default_swsb(struct brw_codegen *p, gen_swsb value)
|
||||
{
|
||||
p->current->swsb = value;
|
||||
}
|
||||
|
||||
void brw_push_insn_state( struct brw_codegen *p )
|
||||
{
|
||||
assert(p->current != &p->stack[BRW_EU_MAX_INSN_STACK-1]);
|
||||
*(p->current + 1) = *p->current;
|
||||
p->current++;
|
||||
}
|
||||
|
||||
void brw_pop_insn_state( struct brw_codegen *p )
|
||||
{
|
||||
assert(p->current != p->stack);
|
||||
p->current--;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*/
|
||||
void
|
||||
brw_init_codegen(const struct brw_isa_info *isa,
|
||||
struct brw_codegen *p, void *mem_ctx)
|
||||
{
|
||||
memset(p, 0, sizeof(*p));
|
||||
|
||||
p->isa = isa;
|
||||
p->devinfo = isa->devinfo;
|
||||
/*
|
||||
* Set the initial instruction store array size to 1024, if found that
|
||||
* isn't enough, then it will double the store size at brw_next_insn()
|
||||
* until out of memory.
|
||||
*/
|
||||
p->store_size = 1024;
|
||||
p->store = rzalloc_array(mem_ctx, brw_eu_inst, p->store_size);
|
||||
p->nr_insn = 0;
|
||||
p->current = p->stack;
|
||||
memset(p->current, 0, sizeof(p->current[0]));
|
||||
|
||||
p->mem_ctx = mem_ctx;
|
||||
|
||||
/* Some defaults?
|
||||
*/
|
||||
brw_set_default_exec_size(p, BRW_EXECUTE_8);
|
||||
brw_set_default_mask_control(p, BRW_MASK_ENABLE); /* what does this do? */
|
||||
brw_set_default_saturate(p, 0);
|
||||
|
||||
/* Set up control flow stack */
|
||||
p->if_stack_depth = 0;
|
||||
p->if_stack_array_size = 16;
|
||||
p->if_stack = rzalloc_array(mem_ctx, int, p->if_stack_array_size);
|
||||
|
||||
p->loop_stack_depth = 0;
|
||||
p->loop_stack_array_size = 16;
|
||||
p->loop_stack = rzalloc_array(mem_ctx, int, p->loop_stack_array_size);
|
||||
}
|
||||
|
||||
|
||||
const unsigned *brw_get_program( struct brw_codegen *p,
|
||||
unsigned *sz )
|
||||
{
|
||||
*sz = p->next_insn_offset;
|
||||
return (const unsigned *)p->store;
|
||||
}
|
||||
|
||||
const struct intel_shader_reloc *
|
||||
brw_get_shader_relocs(struct brw_codegen *p, unsigned *num_relocs)
|
||||
{
|
||||
*num_relocs = p->num_relocs;
|
||||
return p->relocs;
|
||||
}
|
||||
|
||||
DEBUG_GET_ONCE_OPTION(shader_bin_dump_path, "INTEL_SHADER_BIN_DUMP_PATH", NULL);
|
||||
|
||||
bool brw_should_dump_shader_bin(void)
|
||||
|
|
@ -318,220 +152,6 @@ void brw_dump_shader_bin(void *assembly, int start_offset, int end_offset,
|
|||
close(fd);
|
||||
}
|
||||
|
||||
bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
|
||||
const char *read_path, const char *identifier)
|
||||
{
|
||||
char *name = ralloc_asprintf(NULL, "%s/%s.bin", read_path, identifier);
|
||||
|
||||
int fd = open(name, O_RDONLY);
|
||||
ralloc_free(name);
|
||||
|
||||
if (fd == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat sb;
|
||||
if (fstat(fd, &sb) != 0 || (!S_ISREG(sb.st_mode))) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
p->nr_insn -= (p->next_insn_offset - start_offset) / sizeof(brw_eu_inst);
|
||||
p->nr_insn += sb.st_size / sizeof(brw_eu_inst);
|
||||
|
||||
p->next_insn_offset = start_offset + sb.st_size;
|
||||
p->store_size = (start_offset + sb.st_size) / sizeof(brw_eu_inst);
|
||||
p->store = (brw_eu_inst *)reralloc_size(p->mem_ctx, p->store, p->next_insn_offset);
|
||||
assert(p->store);
|
||||
|
||||
ssize_t ret = read(fd, (char *)p->store + start_offset, sb.st_size);
|
||||
close(fd);
|
||||
if (ret != sb.st_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ASSERTED bool valid =
|
||||
brw_validate_instructions(p->isa, p->store,
|
||||
start_offset, p->next_insn_offset,
|
||||
NULL);
|
||||
assert(valid);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct brw_label *
|
||||
brw_find_label(const struct brw_label *root, int offset)
|
||||
{
|
||||
const struct brw_label *curr = root;
|
||||
|
||||
if (curr != NULL)
|
||||
{
|
||||
do {
|
||||
if (curr->offset == offset)
|
||||
return curr;
|
||||
|
||||
curr = curr->next;
|
||||
} while (curr != NULL);
|
||||
}
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
void
|
||||
brw_create_label(struct brw_label **labels, int offset, void *mem_ctx)
|
||||
{
|
||||
if (*labels != NULL) {
|
||||
struct brw_label *curr = *labels;
|
||||
struct brw_label *prev;
|
||||
|
||||
do {
|
||||
prev = curr;
|
||||
|
||||
if (curr->offset == offset)
|
||||
return;
|
||||
|
||||
curr = curr->next;
|
||||
} while (curr != NULL);
|
||||
|
||||
curr = ralloc(mem_ctx, struct brw_label);
|
||||
curr->offset = offset;
|
||||
curr->number = prev->number + 1;
|
||||
curr->next = NULL;
|
||||
prev->next = curr;
|
||||
} else {
|
||||
struct brw_label *root = ralloc(mem_ctx, struct brw_label);
|
||||
root->number = 0;
|
||||
root->offset = offset;
|
||||
root->next = NULL;
|
||||
*labels = root;
|
||||
}
|
||||
}
|
||||
|
||||
const struct brw_label *
|
||||
brw_label_assembly(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start, int end, void *mem_ctx)
|
||||
{
|
||||
const struct intel_device_info *const devinfo = isa->devinfo;
|
||||
|
||||
struct brw_label *root_label = NULL;
|
||||
|
||||
int to_bytes_scale = sizeof(brw_eu_inst) / brw_jump_scale(devinfo);
|
||||
|
||||
for (int offset = start; offset < end;) {
|
||||
const brw_eu_inst *inst = (const brw_eu_inst *) ((const char *) assembly + offset);
|
||||
brw_eu_inst uncompacted;
|
||||
|
||||
bool is_compact = brw_eu_inst_cmpt_control(devinfo, inst);
|
||||
|
||||
if (is_compact) {
|
||||
brw_eu_compact_inst *compacted = (brw_eu_compact_inst *)inst;
|
||||
brw_uncompact_instruction(isa, &uncompacted, compacted);
|
||||
inst = &uncompacted;
|
||||
}
|
||||
|
||||
if (brw_has_uip(devinfo, brw_eu_inst_opcode(isa, inst))) {
|
||||
/* Instructions that have UIP also have JIP. */
|
||||
brw_create_label(&root_label,
|
||||
offset + brw_eu_inst_uip(devinfo, inst) * to_bytes_scale, mem_ctx);
|
||||
brw_create_label(&root_label,
|
||||
offset + brw_eu_inst_jip(devinfo, inst) * to_bytes_scale, mem_ctx);
|
||||
} else if (brw_has_jip(devinfo, brw_eu_inst_opcode(isa, inst))) {
|
||||
int jip = brw_eu_inst_jip(devinfo, inst);
|
||||
|
||||
brw_create_label(&root_label, offset + jip * to_bytes_scale, mem_ctx);
|
||||
}
|
||||
|
||||
if (is_compact) {
|
||||
offset += sizeof(brw_eu_compact_inst);
|
||||
} else {
|
||||
offset += sizeof(brw_eu_inst);
|
||||
}
|
||||
}
|
||||
|
||||
return root_label;
|
||||
}
|
||||
|
||||
void
|
||||
brw_disassemble_with_labels(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start, int end, FILE *out)
|
||||
{
|
||||
void *mem_ctx = ralloc_context(NULL);
|
||||
const struct brw_label *root_label =
|
||||
brw_label_assembly(isa, assembly, start, end, mem_ctx);
|
||||
|
||||
brw_disassemble(isa, assembly, start, end, root_label, NULL, out);
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
void
|
||||
brw_disassemble(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start, int end,
|
||||
const struct brw_label *root_label,
|
||||
int64_t *lineno_offset, FILE *out)
|
||||
{
|
||||
const struct intel_device_info *devinfo = isa->devinfo;
|
||||
|
||||
bool dump_hex = INTEL_DEBUG(DEBUG_HEX);
|
||||
|
||||
for (int offset = start; offset < end;) {
|
||||
const brw_eu_inst *insn = (const brw_eu_inst *)((char *)assembly + offset);
|
||||
brw_eu_inst uncompacted;
|
||||
|
||||
if (root_label != NULL) {
|
||||
const struct brw_label *label = brw_find_label(root_label, offset);
|
||||
if (label != NULL) {
|
||||
fprintf(out, "\nLABEL%d:\n", label->number);
|
||||
}
|
||||
}
|
||||
|
||||
bool compacted = brw_eu_inst_cmpt_control(devinfo, insn);
|
||||
if (lineno_offset)
|
||||
fprintf(out, "0x%08" PRIx64 ": ", *lineno_offset + offset);
|
||||
|
||||
if (compacted) {
|
||||
brw_eu_compact_inst *compacted = (brw_eu_compact_inst *)insn;
|
||||
if (dump_hex) {
|
||||
unsigned char * insn_ptr = ((unsigned char *)&insn[0]);
|
||||
const unsigned int blank_spaces = 24;
|
||||
for (int i = 0 ; i < 8; i = i + 4) {
|
||||
fprintf(out, "%02x %02x %02x %02x ",
|
||||
insn_ptr[i],
|
||||
insn_ptr[i + 1],
|
||||
insn_ptr[i + 2],
|
||||
insn_ptr[i + 3]);
|
||||
}
|
||||
/* Make compacted instructions hex value output vertically aligned
|
||||
* with uncompacted instructions hex value
|
||||
*/
|
||||
fprintf(out, "%*c", blank_spaces, ' ');
|
||||
}
|
||||
|
||||
brw_uncompact_instruction(isa, &uncompacted, compacted);
|
||||
insn = &uncompacted;
|
||||
} else {
|
||||
if (dump_hex) {
|
||||
unsigned char * insn_ptr = ((unsigned char *)&insn[0]);
|
||||
for (int i = 0 ; i < 16; i = i + 4) {
|
||||
fprintf(out, "%02x %02x %02x %02x ",
|
||||
insn_ptr[i],
|
||||
insn_ptr[i + 1],
|
||||
insn_ptr[i + 2],
|
||||
insn_ptr[i + 3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
brw_disassemble_inst(out, isa, insn, compacted, offset, root_label);
|
||||
|
||||
if (compacted) {
|
||||
offset += sizeof(brw_eu_compact_inst);
|
||||
} else {
|
||||
offset += sizeof(brw_eu_inst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct opcode_desc opcode_descs[] = {
|
||||
/* IR, HW, name, nsrc, ndst, gfx_vers assuming Gfx9+ */
|
||||
{ BRW_OPCODE_ILLEGAL, 0, "illegal", 0, 0, GFX_ALL },
|
||||
|
|
@ -679,41 +299,3 @@ brw_opcode_desc_from_hw(const struct brw_isa_info *isa, unsigned hw)
|
|||
{
|
||||
return hw < ARRAY_SIZE(isa->hw_to_descs) ? isa->hw_to_descs[hw] : NULL;
|
||||
}
|
||||
|
||||
unsigned
|
||||
brw_num_sources_from_inst(const struct brw_isa_info *isa,
|
||||
const brw_eu_inst *inst)
|
||||
{
|
||||
const struct intel_device_info *devinfo = isa->devinfo;
|
||||
const struct opcode_desc *desc =
|
||||
brw_opcode_desc(isa, brw_eu_inst_opcode(isa, inst));
|
||||
unsigned math_function;
|
||||
|
||||
if (brw_eu_inst_opcode(isa, inst) == BRW_OPCODE_MATH) {
|
||||
math_function = brw_eu_inst_math_function(devinfo, inst);
|
||||
} else {
|
||||
assert(desc->nsrc < 4);
|
||||
return desc->nsrc;
|
||||
}
|
||||
|
||||
switch (math_function) {
|
||||
case GEN_MATH_INV:
|
||||
case GEN_MATH_LOG:
|
||||
case GEN_MATH_EXP:
|
||||
case GEN_MATH_SQRT:
|
||||
case GEN_MATH_RSQ:
|
||||
case GEN_MATH_SIN:
|
||||
case GEN_MATH_COS:
|
||||
case GEN_MATH_INVM:
|
||||
case GEN_MATH_RSQRTM:
|
||||
return 1;
|
||||
case GEN_MATH_FDIV:
|
||||
case GEN_MATH_POW:
|
||||
case GEN_MATH_INT_DIV_BOTH:
|
||||
case GEN_MATH_INT_DIV_QUOTIENT:
|
||||
case GEN_MATH_INT_DIV_REMAINDER:
|
||||
return 2;
|
||||
default:
|
||||
UNREACHABLE("not reached");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "brw_eu_inst.h"
|
||||
#include "brw_compiler.h"
|
||||
#include "brw_eu_defines.h"
|
||||
#include "brw_isa_info.h"
|
||||
|
|
@ -25,219 +24,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct disasm_info;
|
||||
|
||||
#define BRW_EU_MAX_INSN_STACK 5
|
||||
|
||||
struct brw_insn_state {
|
||||
/* One of BRW_EXECUTE_* */
|
||||
unsigned exec_size:3;
|
||||
|
||||
/* Group in units of channels */
|
||||
unsigned group:5;
|
||||
|
||||
/* One of BRW_MASK_* */
|
||||
unsigned mask_control:1;
|
||||
|
||||
/* Scheduling info for Gfx12+ */
|
||||
gen_swsb swsb;
|
||||
|
||||
bool saturate:1;
|
||||
|
||||
/* One of BRW_ALIGN_* */
|
||||
unsigned access_mode:1;
|
||||
|
||||
/* One of BRW_PREDICATE_* */
|
||||
enum brw_predicate predicate:4;
|
||||
|
||||
bool pred_inv:1;
|
||||
|
||||
/* Flag subreg. Bottom bit is subreg, top bits are reg */
|
||||
unsigned flag_subreg:3;
|
||||
|
||||
bool acc_wr_control:1;
|
||||
};
|
||||
|
||||
struct brw_codegen {
|
||||
brw_eu_inst *store;
|
||||
int store_size;
|
||||
unsigned nr_insn;
|
||||
unsigned int next_insn_offset;
|
||||
|
||||
void *mem_ctx;
|
||||
|
||||
/* Allow clients to push/pop instruction state:
|
||||
*/
|
||||
struct brw_insn_state stack[BRW_EU_MAX_INSN_STACK];
|
||||
struct brw_insn_state *current;
|
||||
|
||||
const struct brw_isa_info *isa;
|
||||
const struct intel_device_info *devinfo;
|
||||
|
||||
/* Control flow stacks:
|
||||
* - if_stack contains IF and ELSE instructions which must be patched
|
||||
* (and popped) once the matching ENDIF instruction is encountered.
|
||||
*
|
||||
* Just store the instruction pointer(an index).
|
||||
*/
|
||||
int *if_stack;
|
||||
int if_stack_depth;
|
||||
int if_stack_array_size;
|
||||
|
||||
/**
|
||||
* loop_stack contains the instruction pointers of the starts of loops which
|
||||
* must be patched (and popped) once the matching WHILE instruction is
|
||||
* encountered.
|
||||
*/
|
||||
int *loop_stack;
|
||||
int loop_stack_depth;
|
||||
int loop_stack_array_size;
|
||||
|
||||
struct intel_shader_reloc *relocs;
|
||||
int num_relocs;
|
||||
int reloc_array_size;
|
||||
};
|
||||
|
||||
struct brw_label {
|
||||
int offset;
|
||||
int number;
|
||||
struct brw_label *next;
|
||||
};
|
||||
|
||||
static inline brw_eu_inst *
|
||||
brw_eu_last_inst(struct brw_codegen *p)
|
||||
{
|
||||
return &p->store[p->nr_insn - 1];
|
||||
}
|
||||
|
||||
void brw_pop_insn_state( struct brw_codegen *p );
|
||||
void brw_push_insn_state( struct brw_codegen *p );
|
||||
unsigned brw_get_default_exec_size(struct brw_codegen *p);
|
||||
unsigned brw_get_default_group(struct brw_codegen *p);
|
||||
unsigned brw_get_default_access_mode(struct brw_codegen *p);
|
||||
gen_swsb brw_get_default_swsb(struct brw_codegen *p);
|
||||
void brw_set_default_exec_size(struct brw_codegen *p, unsigned value);
|
||||
void brw_set_default_mask_control( struct brw_codegen *p, unsigned value );
|
||||
void brw_set_default_saturate( struct brw_codegen *p, bool enable );
|
||||
void brw_set_default_access_mode( struct brw_codegen *p, unsigned access_mode );
|
||||
void brw_eu_inst_set_group(const struct intel_device_info *devinfo,
|
||||
brw_eu_inst *inst, unsigned group);
|
||||
void brw_set_default_group(struct brw_codegen *p, unsigned group);
|
||||
void brw_set_default_predicate_control(struct brw_codegen *p, enum brw_predicate pc);
|
||||
void brw_set_default_predicate_inverse(struct brw_codegen *p, bool predicate_inverse);
|
||||
void brw_set_default_flag_reg(struct brw_codegen *p, int reg, int subreg);
|
||||
void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value);
|
||||
void brw_set_default_swsb(struct brw_codegen *p, gen_swsb value);
|
||||
|
||||
uint32_t brw_swsb_encode(const struct intel_device_info *devinfo,
|
||||
gen_swsb swsb, enum opcode op);
|
||||
gen_swsb brw_swsb_decode(const struct intel_device_info *devinfo,
|
||||
bool is_unordered, uint32_t raw, enum opcode op);
|
||||
|
||||
void brw_init_codegen(const struct brw_isa_info *isa,
|
||||
struct brw_codegen *p, void *mem_ctx);
|
||||
bool brw_has_jip(const struct intel_device_info *devinfo, enum opcode opcode);
|
||||
bool brw_has_uip(const struct intel_device_info *devinfo, enum opcode opcode);
|
||||
bool brw_has_branch_ctrl(const struct intel_device_info *devinfo, enum opcode opcode);
|
||||
const struct intel_shader_reloc *brw_get_shader_relocs(struct brw_codegen *p,
|
||||
unsigned *num_relocs);
|
||||
const unsigned *brw_get_program( struct brw_codegen *p, unsigned *sz );
|
||||
|
||||
bool brw_should_dump_shader_bin(void);
|
||||
void brw_dump_shader_bin(void *assembly, int start_offset, int end_offset,
|
||||
const char *identifier);
|
||||
|
||||
bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
|
||||
const char *read_path, const char *identifier);
|
||||
|
||||
void brw_realign(struct brw_codegen *p, unsigned alignment);
|
||||
int brw_append_data(struct brw_codegen *p, void *data,
|
||||
unsigned size, unsigned alignment);
|
||||
brw_eu_inst *brw_next_insn(struct brw_codegen *p, unsigned opcode);
|
||||
void brw_add_reloc(struct brw_codegen *p, uint32_t id,
|
||||
enum intel_shader_reloc_type type,
|
||||
uint32_t offset, uint32_t delta);
|
||||
void brw_set_dest(struct brw_codegen *p, brw_eu_inst *insn, struct brw_reg dest);
|
||||
void brw_set_src0(struct brw_codegen *p, brw_eu_inst *insn, struct brw_reg reg);
|
||||
|
||||
brw_eu_inst *brw_alu1(struct brw_codegen *p, unsigned opcode, struct brw_reg dest,
|
||||
struct brw_reg src);
|
||||
brw_eu_inst *brw_alu2(struct brw_codegen *p, unsigned opcode, struct brw_reg dest,
|
||||
struct brw_reg src0, struct brw_reg src1);
|
||||
brw_eu_inst *brw_alu3(struct brw_codegen *p, unsigned opcode, struct brw_reg dest,
|
||||
struct brw_reg src0, struct brw_reg src1, struct brw_reg src2);
|
||||
|
||||
/* Helpers for regular instructions:
|
||||
*/
|
||||
#define ALU1(OP) \
|
||||
brw_eu_inst *brw_##OP(struct brw_codegen *p, \
|
||||
struct brw_reg dest, \
|
||||
struct brw_reg src0);
|
||||
|
||||
#define ALU2(OP) \
|
||||
brw_eu_inst *brw_##OP(struct brw_codegen *p, \
|
||||
struct brw_reg dest, \
|
||||
struct brw_reg src0, \
|
||||
struct brw_reg src1);
|
||||
|
||||
#define ALU3(OP) \
|
||||
brw_eu_inst *brw_##OP(struct brw_codegen *p, \
|
||||
struct brw_reg dest, \
|
||||
struct brw_reg src0, \
|
||||
struct brw_reg src1, \
|
||||
struct brw_reg src2);
|
||||
|
||||
ALU1(MOV)
|
||||
ALU2(SEL)
|
||||
ALU1(NOT)
|
||||
ALU2(AND)
|
||||
ALU2(OR)
|
||||
ALU2(XOR)
|
||||
ALU2(SHR)
|
||||
ALU2(SHL)
|
||||
ALU1(DIM)
|
||||
ALU2(ASR)
|
||||
ALU2(ROL)
|
||||
ALU2(ROR)
|
||||
ALU3(CSEL)
|
||||
ALU1(F32TO16)
|
||||
ALU1(F16TO32)
|
||||
ALU2(ADD)
|
||||
ALU3(ADD3)
|
||||
ALU2(AVG)
|
||||
ALU2(MUL)
|
||||
ALU1(FRC)
|
||||
ALU1(RNDD)
|
||||
ALU1(RNDE)
|
||||
ALU1(RNDU)
|
||||
ALU1(RNDZ)
|
||||
ALU2(MAC)
|
||||
ALU2(MACL)
|
||||
ALU2(MACH)
|
||||
ALU1(LZD)
|
||||
ALU2(DP4)
|
||||
ALU2(DPH)
|
||||
ALU2(DP3)
|
||||
ALU2(DP2)
|
||||
ALU3(DP4A)
|
||||
ALU2(LINE)
|
||||
ALU2(PLN)
|
||||
ALU3(MAD)
|
||||
ALU3(LRP)
|
||||
ALU1(BFREV)
|
||||
ALU3(BFE)
|
||||
ALU2(BFI1)
|
||||
ALU3(BFI2)
|
||||
ALU1(FBH)
|
||||
ALU1(FBL)
|
||||
ALU1(CBIT)
|
||||
ALU2(ADDC)
|
||||
ALU2(SUBB)
|
||||
|
||||
#undef ALU1
|
||||
#undef ALU2
|
||||
#undef ALU3
|
||||
|
||||
/* In Xe2+ each register is 64bytes/512bits long while older platforms it is
|
||||
* 32bytes/256bits long.
|
||||
*/
|
||||
|
|
@ -1054,179 +844,9 @@ brw_pixel_interp_desc(UNUSED const struct intel_device_info *devinfo,
|
|||
SET_BITS(simd_mode, 16, 16));
|
||||
}
|
||||
|
||||
static inline enum gfx12_systolic_depth
|
||||
translate_systolic_depth(unsigned d)
|
||||
{
|
||||
/* Could also return (ffs(d) - 1) & 3. */
|
||||
switch (d) {
|
||||
case 2: return BRW_SYSTOLIC_DEPTH_2;
|
||||
case 4: return BRW_SYSTOLIC_DEPTH_4;
|
||||
case 8: return BRW_SYSTOLIC_DEPTH_8;
|
||||
case 16: return BRW_SYSTOLIC_DEPTH_16;
|
||||
default: UNREACHABLE("Invalid systolic depth.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brw_SEND(struct brw_codegen *p,
|
||||
unsigned sfid,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg payload0,
|
||||
struct brw_reg payload1,
|
||||
struct brw_reg desc,
|
||||
struct brw_reg ex_desc,
|
||||
uint32_t ex_desc_imm_inst,
|
||||
unsigned ex_mlen,
|
||||
bool ex_bso,
|
||||
bool eot,
|
||||
bool gather);
|
||||
|
||||
void gfx6_math(struct brw_codegen *p,
|
||||
struct brw_reg dest,
|
||||
unsigned function,
|
||||
struct brw_reg src0,
|
||||
struct brw_reg src1);
|
||||
|
||||
/**
|
||||
* Return the generation-specific jump distance scaling factor.
|
||||
*
|
||||
* Given the number of instructions to jump, we need to scale by
|
||||
* some number to obtain the actual jump distance to program in an
|
||||
* instruction.
|
||||
*/
|
||||
static inline unsigned
|
||||
brw_jump_scale(const struct intel_device_info *devinfo)
|
||||
{
|
||||
/* Broadwell measures jump targets in bytes. */
|
||||
return 16;
|
||||
}
|
||||
|
||||
void brw_barrier(struct brw_codegen *p, struct brw_reg src);
|
||||
|
||||
/* If/else/endif. Works by manipulating the execution flags on each
|
||||
* channel.
|
||||
*/
|
||||
brw_eu_inst *brw_IF(struct brw_codegen *p, unsigned execute_size);
|
||||
|
||||
void brw_ELSE(struct brw_codegen *p);
|
||||
void brw_ENDIF(struct brw_codegen *p);
|
||||
|
||||
brw_eu_inst *brw_BFN(struct brw_codegen *p, struct brw_reg dest,
|
||||
struct brw_reg src0, struct brw_reg src1,
|
||||
struct brw_reg src2, struct brw_reg table_byte);
|
||||
|
||||
/* DO/WHILE loops:
|
||||
*/
|
||||
brw_eu_inst *brw_DO(struct brw_codegen *p, unsigned execute_size);
|
||||
|
||||
brw_eu_inst *brw_WHILE(struct brw_codegen *p);
|
||||
|
||||
brw_eu_inst *brw_BREAK(struct brw_codegen *p);
|
||||
brw_eu_inst *brw_CONT(struct brw_codegen *p);
|
||||
brw_eu_inst *brw_HALT(struct brw_codegen *p);
|
||||
|
||||
/* Forward jumps:
|
||||
*/
|
||||
brw_eu_inst *brw_JMPI(struct brw_codegen *p, struct brw_reg index,
|
||||
unsigned predicate_control);
|
||||
|
||||
void brw_NOP(struct brw_codegen *p);
|
||||
|
||||
void brw_WAIT(struct brw_codegen *p);
|
||||
|
||||
void brw_SYNC(struct brw_codegen *p, enum tgl_sync_function func);
|
||||
|
||||
/* Special case: there is never a destination, execution size will be
|
||||
* taken from src0:
|
||||
*/
|
||||
void brw_CMP(struct brw_codegen *p,
|
||||
struct brw_reg dest,
|
||||
unsigned conditional,
|
||||
struct brw_reg src0,
|
||||
struct brw_reg src1);
|
||||
|
||||
void brw_CMPN(struct brw_codegen *p,
|
||||
struct brw_reg dest,
|
||||
unsigned conditional,
|
||||
struct brw_reg src0,
|
||||
struct brw_reg src1);
|
||||
|
||||
brw_eu_inst *brw_DPAS(struct brw_codegen *p, enum gfx12_systolic_depth sdepth,
|
||||
unsigned rcount, struct brw_reg dest, struct brw_reg src0,
|
||||
struct brw_reg src1, struct brw_reg src2);
|
||||
|
||||
brw_eu_inst *brw_SRND(struct brw_codegen *p, struct brw_reg dest,
|
||||
struct brw_reg src0, struct brw_reg src1);
|
||||
|
||||
void
|
||||
brw_broadcast(struct brw_codegen *p,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src,
|
||||
struct brw_reg idx);
|
||||
|
||||
void
|
||||
brw_float_controls_mode(struct brw_codegen *p,
|
||||
unsigned mode, unsigned mask);
|
||||
|
||||
void
|
||||
brw_MOV_reloc_imm(struct brw_codegen *p,
|
||||
struct brw_reg dst,
|
||||
enum brw_reg_type src_type,
|
||||
uint32_t id, uint32_t base);
|
||||
|
||||
unsigned
|
||||
brw_num_sources_from_inst(const struct brw_isa_info *isa,
|
||||
const brw_eu_inst *inst);
|
||||
|
||||
void brw_set_src1(struct brw_codegen *p, brw_eu_inst *insn, struct brw_reg reg);
|
||||
|
||||
void brw_set_desc_ex(struct brw_codegen *p, brw_eu_inst *insn,
|
||||
unsigned desc, unsigned ex_desc, bool gather);
|
||||
|
||||
static inline void
|
||||
brw_set_desc(struct brw_codegen *p, brw_eu_inst *insn, unsigned desc, bool gather)
|
||||
{
|
||||
brw_set_desc_ex(p, insn, desc, 0, gather);
|
||||
}
|
||||
|
||||
void brw_set_uip_jip(struct brw_codegen *p, int start_offset, int final_halt_offset);
|
||||
|
||||
enum brw_conditional_mod brw_negate_cmod(enum brw_conditional_mod cmod);
|
||||
enum brw_conditional_mod brw_swap_cmod(enum brw_conditional_mod cmod);
|
||||
|
||||
/* brw_eu_compact.c */
|
||||
void brw_compact_instructions(struct brw_codegen *p, int start_offset,
|
||||
struct disasm_info *disasm);
|
||||
void brw_uncompact_instruction(const struct brw_isa_info *isa,
|
||||
brw_eu_inst *dst, brw_eu_compact_inst *src);
|
||||
bool brw_try_compact_instruction(const struct brw_isa_info *isa,
|
||||
brw_eu_compact_inst *dst, const brw_eu_inst *src);
|
||||
|
||||
void brw_debug_compact_uncompact(const struct brw_isa_info *isa,
|
||||
brw_eu_inst *orig, brw_eu_inst *uncompacted);
|
||||
|
||||
/* brw_eu_validate.c */
|
||||
bool brw_validate_instruction(const struct brw_isa_info *isa,
|
||||
const brw_eu_inst *inst, int offset,
|
||||
unsigned inst_size,
|
||||
struct disasm_info *disasm);
|
||||
bool brw_validate_instructions(const struct brw_isa_info *isa,
|
||||
const void *assembly, int start_offset, int end_offset,
|
||||
struct disasm_info *disasm);
|
||||
|
||||
static inline int
|
||||
next_offset(struct brw_codegen *p, void *store, int offset)
|
||||
{
|
||||
const struct intel_device_info *devinfo = p->devinfo;
|
||||
assert((char *)store + offset < (char *)p->store + p->next_insn_offset);
|
||||
brw_eu_inst *insn = (brw_eu_inst *)((char *)store + offset);
|
||||
|
||||
if (brw_eu_inst_cmpt_control(devinfo, insn))
|
||||
return offset + 8;
|
||||
else
|
||||
return offset + 16;
|
||||
}
|
||||
|
||||
/** Maximum SEND message length */
|
||||
#define BRW_MAX_MSG_LENGTH 15
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2010 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "brw_shader.h"
|
||||
|
||||
namespace old {
|
||||
|
||||
/* Translates BRW IR to actual EU assembly code. */
|
||||
class brw_generator
|
||||
{
|
||||
public:
|
||||
brw_generator(const struct brw_compiler *compiler,
|
||||
const struct brw_compile_params *params,
|
||||
struct brw_stage_prog_data *prog_data,
|
||||
mesa_shader_stage stage);
|
||||
~brw_generator();
|
||||
|
||||
void enable_debug(const char *shader_name);
|
||||
int generate_code(const brw_shader &s,
|
||||
struct genisa_stats *stats);
|
||||
void add_const_data(void *data, unsigned size);
|
||||
void add_resume_sbt(unsigned num_resume_shaders, uint64_t *sbt);
|
||||
const unsigned *get_assembly();
|
||||
|
||||
private:
|
||||
void generate_send(brw_send_inst *inst,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg desc,
|
||||
struct brw_reg ex_desc,
|
||||
struct brw_reg payload,
|
||||
struct brw_reg payload2,
|
||||
bool ex_bso);
|
||||
void generate_barrier(brw_inst *inst, struct brw_reg src);
|
||||
void generate_ddx(const brw_inst *inst,
|
||||
struct brw_reg dst, struct brw_reg src);
|
||||
void generate_ddy(const brw_inst *inst,
|
||||
struct brw_reg dst, struct brw_reg src);
|
||||
void generate_scratch_header(brw_inst *inst,
|
||||
struct brw_reg dst, struct brw_reg src);
|
||||
|
||||
void generate_mov_indirect(brw_inst *inst,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg reg,
|
||||
struct brw_reg indirect_byte_offset);
|
||||
|
||||
void generate_shuffle(brw_inst *inst,
|
||||
struct brw_reg dst,
|
||||
struct brw_reg src,
|
||||
struct brw_reg idx);
|
||||
|
||||
void generate_quad_swizzle(const brw_inst *inst,
|
||||
struct brw_reg dst, struct brw_reg src,
|
||||
unsigned swiz);
|
||||
|
||||
bool patch_halt_jumps();
|
||||
|
||||
const struct brw_compiler *compiler;
|
||||
const struct brw_compile_params *params;
|
||||
|
||||
const struct intel_device_info *devinfo;
|
||||
|
||||
struct brw_codegen *p;
|
||||
struct brw_stage_prog_data * const prog_data;
|
||||
|
||||
unsigned dispatch_width; /**< 8, 16 or 32 */
|
||||
|
||||
int final_halt_offset;
|
||||
bool needs_final_halt;
|
||||
|
||||
bool debug_flag;
|
||||
const char *shader_name;
|
||||
mesa_shader_stage stage;
|
||||
void *mem_ctx;
|
||||
};
|
||||
|
||||
} /* namespace old */
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,452 +0,0 @@
|
|||
%option yylineno
|
||||
%option nounput
|
||||
%option bison-bridge bison-locations reentrant noyywrap
|
||||
%option extra-type="struct brw_asm_parser *"
|
||||
%option prefix="brw_asm_"
|
||||
%{
|
||||
/*
|
||||
* Copyright © 2018 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "brw_asm_internal.h"
|
||||
#undef ALIGN16
|
||||
#include "brw_gram.tab.h"
|
||||
|
||||
#define YY_NO_INPUT
|
||||
|
||||
#define YY_USER_ACTION \
|
||||
yylloc->first_line = yylloc->last_line = yylineno; \
|
||||
yylloc->first_column = yycolumn; \
|
||||
yylloc->last_column = yycolumn + yyleng - 1; \
|
||||
yycolumn += yyleng;
|
||||
|
||||
#define YY_USER_INIT \
|
||||
do { \
|
||||
yylineno = 1; \
|
||||
yycolumn = 1; \
|
||||
} while (0)
|
||||
%}
|
||||
|
||||
%x BLOCK_COMMENT
|
||||
%x FILENAME
|
||||
%x CHANNEL
|
||||
%x REG
|
||||
%x DOTSEL
|
||||
%x LABEL
|
||||
%x MSGDESC
|
||||
%%
|
||||
|
||||
struct brw_asm_parser *parser = yyextra;
|
||||
struct brw_codegen *p = parser->p;
|
||||
|
||||
/* eat up single line comment */
|
||||
\/\/.*[\r\n] { yycolumn = 1; }
|
||||
|
||||
/* eat up multiline comment */
|
||||
\/\* { parser->saved_state = YYSTATE; BEGIN(BLOCK_COMMENT); }
|
||||
|
||||
<BLOCK_COMMENT>\*\/ { BEGIN(parser->saved_state); }
|
||||
|
||||
<BLOCK_COMMENT>. { }
|
||||
<BLOCK_COMMENT>[\r\n] { }
|
||||
|
||||
<FILENAME>\"[^\"]+\" {
|
||||
char *name = malloc(yyleng - 1);
|
||||
memmove(name, yytext + 1, yyleng - 2);
|
||||
name[yyleng-1] = '\0';
|
||||
parser->input_filename = name;
|
||||
}
|
||||
|
||||
/* null register */
|
||||
null { BEGIN(REG); return NULL_TOKEN; }
|
||||
|
||||
/* Opcodes */
|
||||
add { yylval->integer = BRW_OPCODE_ADD; return ADD; }
|
||||
add3 { yylval->integer = BRW_OPCODE_ADD3; return ADD3; }
|
||||
addc { yylval->integer = BRW_OPCODE_ADDC; return ADDC; }
|
||||
and { yylval->integer = BRW_OPCODE_AND; return AND; }
|
||||
asr { yylval->integer = BRW_OPCODE_ASR; return ASR; }
|
||||
avg { yylval->integer = BRW_OPCODE_AVG; return AVG; }
|
||||
bfe { yylval->integer = BRW_OPCODE_BFE; return BFE; }
|
||||
bfi1 { yylval->integer = BRW_OPCODE_BFI1; return BFI1; }
|
||||
bfi2 { yylval->integer = BRW_OPCODE_BFI2; return BFI2; }
|
||||
bfrev { yylval->integer = BRW_OPCODE_BFREV; return BFREV; }
|
||||
brc { yylval->integer = BRW_OPCODE_BRC; return BRC; }
|
||||
brd { yylval->integer = BRW_OPCODE_BRD; return BRD; }
|
||||
break { yylval->integer = BRW_OPCODE_BREAK; return BREAK; }
|
||||
call { yylval->integer = BRW_OPCODE_CALL; return CALL; }
|
||||
calla { yylval->integer = BRW_OPCODE_CALLA; return CALLA; }
|
||||
cbit { yylval->integer = BRW_OPCODE_CBIT; return CBIT; }
|
||||
cmp { yylval->integer = BRW_OPCODE_CMP; return CMP; }
|
||||
cmpn { yylval->integer = BRW_OPCODE_CMPN; return CMPN; }
|
||||
cont { yylval->integer = BRW_OPCODE_CONTINUE; return CONT; }
|
||||
csel { yylval->integer = BRW_OPCODE_CSEL; return CSEL; }
|
||||
do { yylval->integer = BRW_OPCODE_DO; return DO; }
|
||||
dp2 { yylval->integer = BRW_OPCODE_DP2; return DP2; }
|
||||
dp3 { yylval->integer = BRW_OPCODE_DP3; return DP3; }
|
||||
dp4 { yylval->integer = BRW_OPCODE_DP4; return DP4; }
|
||||
dp4a { yylval->integer = BRW_OPCODE_DP4A; return DP4A; }
|
||||
dpas { yylval->integer = BRW_OPCODE_DPAS; return DPAS; }
|
||||
dph { yylval->integer = BRW_OPCODE_DPH; return DPH; }
|
||||
else { yylval->integer = BRW_OPCODE_ELSE; return ELSE; }
|
||||
endif { yylval->integer = BRW_OPCODE_ENDIF; return ENDIF; }
|
||||
fbh { yylval->integer = BRW_OPCODE_FBH; return FBH; }
|
||||
fbl { yylval->integer = BRW_OPCODE_FBL; return FBL; }
|
||||
frc { yylval->integer = BRW_OPCODE_FRC; return FRC; }
|
||||
goto { yylval->integer = BRW_OPCODE_GOTO; return GOTO; }
|
||||
halt { yylval->integer = BRW_OPCODE_HALT; return HALT; }
|
||||
if { yylval->integer = BRW_OPCODE_IF; return IF; }
|
||||
illegal { yylval->integer = BRW_OPCODE_ILLEGAL; return ILLEGAL; }
|
||||
join { yylval->integer = BRW_OPCODE_JOIN; return JOIN; }
|
||||
jmpi { yylval->integer = BRW_OPCODE_JMPI; return JMPI; }
|
||||
line { yylval->integer = BRW_OPCODE_LINE; return LINE; }
|
||||
lrp { yylval->integer = BRW_OPCODE_LRP; return LRP; }
|
||||
lzd { yylval->integer = BRW_OPCODE_LZD; return LZD; }
|
||||
mac { yylval->integer = BRW_OPCODE_MAC; return MAC; }
|
||||
mach { yylval->integer = BRW_OPCODE_MACH; return MACH; }
|
||||
mad { yylval->integer = BRW_OPCODE_MAD; return MAD; }
|
||||
madm { yylval->integer = BRW_OPCODE_MADM; return MADM; }
|
||||
mov { yylval->integer = BRW_OPCODE_MOV; return MOV; }
|
||||
movi { yylval->integer = BRW_OPCODE_MOVI; return MOVI; }
|
||||
mul { yylval->integer = BRW_OPCODE_MUL; return MUL; }
|
||||
nop { yylval->integer = BRW_OPCODE_NOP; return NOP; }
|
||||
not { yylval->integer = BRW_OPCODE_NOT; return NOT; }
|
||||
or { yylval->integer = BRW_OPCODE_OR; return OR; }
|
||||
pln { yylval->integer = BRW_OPCODE_PLN; return PLN; }
|
||||
ret { yylval->integer = BRW_OPCODE_RET; return RET; }
|
||||
rndd { yylval->integer = BRW_OPCODE_RNDD; return RNDD; }
|
||||
rnde { yylval->integer = BRW_OPCODE_RNDE; return RNDE; }
|
||||
rndu { yylval->integer = BRW_OPCODE_RNDU; return RNDU; }
|
||||
rndz { yylval->integer = BRW_OPCODE_RNDZ; return RNDZ; }
|
||||
rol { yylval->integer = BRW_OPCODE_ROL; return ROL; }
|
||||
ror { yylval->integer = BRW_OPCODE_ROR; return ROR; }
|
||||
sel { yylval->integer = BRW_OPCODE_SEL; return SEL; }
|
||||
send {
|
||||
yylval->integer = BRW_OPCODE_SEND;
|
||||
return parser->devinfo->ver < 12 ? SEND_GFX4 : SEND_GFX12;
|
||||
}
|
||||
sendc {
|
||||
yylval->integer = BRW_OPCODE_SENDC;
|
||||
return parser->devinfo->ver < 12 ? SENDC_GFX4 : SENDC_GFX12;
|
||||
}
|
||||
sends { yylval->integer = BRW_OPCODE_SENDS; return SENDS; }
|
||||
sendsc { yylval->integer = BRW_OPCODE_SENDSC; return SENDSC; }
|
||||
shl { yylval->integer = BRW_OPCODE_SHL; return SHL; }
|
||||
shr { yylval->integer = BRW_OPCODE_SHR; return SHR; }
|
||||
smov { yylval->integer = BRW_OPCODE_SMOV; return SMOV; }
|
||||
srnd { yylval->integer = BRW_OPCODE_SRND; return SRND; }
|
||||
subb { yylval->integer = BRW_OPCODE_SUBB; return SUBB; }
|
||||
wait { yylval->integer = BRW_OPCODE_WAIT; return WAIT; }
|
||||
while { yylval->integer = BRW_OPCODE_WHILE; return WHILE; }
|
||||
xor { yylval->integer = BRW_OPCODE_XOR; return XOR; }
|
||||
sync { yylval->integer = BRW_OPCODE_SYNC; return SYNC; }
|
||||
math { yylval->integer = BRW_OPCODE_MATH; return MATH; }
|
||||
|
||||
/* extended math functions */
|
||||
cos { yylval->integer = GEN_MATH_COS; return COS; }
|
||||
exp { yylval->integer = GEN_MATH_EXP; return EXP; }
|
||||
fdiv { yylval->integer = GEN_MATH_FDIV; return FDIV; }
|
||||
inv { yylval->integer = GEN_MATH_INV; return INV; }
|
||||
invm { yylval->integer = GEN_MATH_INVM; return INVM; }
|
||||
intdiv {
|
||||
yylval->integer = GEN_MATH_INT_DIV_QUOTIENT;
|
||||
return INTDIV;
|
||||
}
|
||||
intdivmod {
|
||||
yylval->integer =
|
||||
GEN_MATH_INT_DIV_BOTH;
|
||||
return INTDIVMOD;
|
||||
}
|
||||
intmod {
|
||||
yylval->integer = GEN_MATH_INT_DIV_REMAINDER;
|
||||
return INTMOD;
|
||||
}
|
||||
log { yylval->integer = GEN_MATH_LOG; return LOG; }
|
||||
pow { yylval->integer = GEN_MATH_POW; return POW; }
|
||||
rsq { yylval->integer = GEN_MATH_RSQ; return RSQ; }
|
||||
rsqrtm { yylval->integer = GEN_MATH_RSQRTM; return RSQRTM; }
|
||||
sin { yylval->integer = GEN_MATH_SIN; return SIN; }
|
||||
sqrt { yylval->integer = GEN_MATH_SQRT; return SQRT; }
|
||||
|
||||
/* sync instruction */
|
||||
allrd { yylval->integer = TGL_SYNC_ALLRD; return ALLRD; }
|
||||
allwr { yylval->integer = TGL_SYNC_ALLWR; return ALLWR; }
|
||||
fence { yylval->integer = TGL_SYNC_FENCE; return FENCE; }
|
||||
bar { yylval->integer = TGL_SYNC_BAR; return BAR; }
|
||||
host { yylval->integer = TGL_SYNC_HOST; return HOST; }
|
||||
|
||||
/* shared functions for send instruction */
|
||||
gateway { return GATEWAY; }
|
||||
hdc0 { return HDC0; }
|
||||
hdc1 { return HDC1; }
|
||||
hdc2 { return HDC2; }
|
||||
"hdc:ro" { return HDC_RO; }
|
||||
pi { return PIXEL_INTERP; }
|
||||
render { return RENDER; }
|
||||
"rt accel" { return RT_ACCEL; }
|
||||
sampler { return SAMPLER; }
|
||||
"ts/btd" { return TS_BTD; }
|
||||
urb { return URB; }
|
||||
slm { return SLM; }
|
||||
tgm { return TGM; }
|
||||
ugm { return UGM; }
|
||||
|
||||
";" { return SEMICOLON; }
|
||||
":" { return COLON; }
|
||||
"(" { return LPAREN; }
|
||||
")" { return RPAREN; }
|
||||
"{" { return LCURLY; }
|
||||
"}" { return RCURLY; }
|
||||
"[" { return LSQUARE; }
|
||||
"]" { return RSQUARE; }
|
||||
"<" { return LANGLE; }
|
||||
">" { return RANGLE; }
|
||||
"," { return COMMA; }
|
||||
"." { return DOT; }
|
||||
"+" { return PLUS; }
|
||||
"-" { return MINUS; }
|
||||
"~" { return MINUS; }
|
||||
"(abs)" { return ABS; }
|
||||
|
||||
|
||||
"VxH" { return VxH; }
|
||||
<REG>"<" { return LANGLE; }
|
||||
<REG>[0-9][0-9]* {
|
||||
yylval->integer = strtoul(yytext, NULL, 10);
|
||||
return INTEGER;
|
||||
}
|
||||
<REG>">" { return RANGLE; }
|
||||
<REG>"," { return COMMA; }
|
||||
<REG>"." { BEGIN(DOTSEL); return DOT; }
|
||||
<REG>";" { return SEMICOLON; }
|
||||
|
||||
<DOTSEL>"x" { yylval->integer = BRW_CHANNEL_X; return X; }
|
||||
<DOTSEL>"y" { yylval->integer = BRW_CHANNEL_Y; return Y; }
|
||||
<DOTSEL>"z" { yylval->integer = BRW_CHANNEL_Z; return Z; }
|
||||
<DOTSEL>"w" { yylval->integer = BRW_CHANNEL_W; return W; }
|
||||
<DOTSEL>[0-9][0-9]* {
|
||||
yylval->integer = strtoul(yytext, NULL, 10);
|
||||
BEGIN(REG);
|
||||
return INTEGER;
|
||||
}
|
||||
<DOTSEL>. { yyless(0); BEGIN(INITIAL); }
|
||||
<REG>. { yyless(0); BEGIN(INITIAL); }
|
||||
|
||||
/* Access mode */
|
||||
"align1" { return ALIGN1; }
|
||||
"align16" { return ALIGN16; }
|
||||
|
||||
/* Accumulator write control */
|
||||
AccWrEnable { return ACCWREN; }
|
||||
|
||||
/* Mask control (formerly WECtrl/Write Enable Control) */
|
||||
"WE_all" { return WECTRL; }
|
||||
|
||||
/* Compaction control */
|
||||
compacted { return CMPTCTRL; }
|
||||
|
||||
/* Debug control */
|
||||
breakpoint { return BREAKPOINT; }
|
||||
|
||||
/* Dependency control */
|
||||
NoDDClr { return NODDCLR; }
|
||||
NoDDChk { return NODDCHK; }
|
||||
|
||||
/* End of thread */
|
||||
EOT { return EOT; }
|
||||
|
||||
/* Mask control */
|
||||
nomask { return MASK_DISABLE; }
|
||||
|
||||
/* Channel */
|
||||
<CHANNEL>"x" { yylval->integer = BRW_CHANNEL_X; return X; }
|
||||
<CHANNEL>"y" { yylval->integer = BRW_CHANNEL_Y; return Y; }
|
||||
<CHANNEL>"z" { yylval->integer = BRW_CHANNEL_Z; return Z; }
|
||||
<CHANNEL>"w" { yylval->integer = BRW_CHANNEL_W; return W; }
|
||||
<CHANNEL>[0-9][0-9]* {
|
||||
yylval->integer = strtoul(yytext, NULL, 10);
|
||||
return INTEGER;
|
||||
}
|
||||
<CHANNEL>"." { return DOT; }
|
||||
<CHANNEL>. { yyless(0); BEGIN(INITIAL); }
|
||||
|
||||
|
||||
/* Predicate Control */
|
||||
<CHANNEL>".anyv" { yylval->integer = BRW_PREDICATE_ALIGN1_ANYV; return ANYV; }
|
||||
<CHANNEL>".allv" { yylval->integer = BRW_PREDICATE_ALIGN1_ALLV; return ALLV; }
|
||||
<CHANNEL>".any2h" { yylval->integer = BRW_PREDICATE_ALIGN1_ANY2H; return ANY2H; }
|
||||
<CHANNEL>".all2h" { yylval->integer = BRW_PREDICATE_ALIGN1_ALL2H; return ALL2H; }
|
||||
<CHANNEL>".any4h" { yylval->integer = BRW_PREDICATE_ALIGN16_ANY4H; return ANY4H; }
|
||||
<CHANNEL>".all4h" { yylval->integer = BRW_PREDICATE_ALIGN16_ALL4H; return ALL4H; }
|
||||
<CHANNEL>".any8h" { yylval->integer = BRW_PREDICATE_ALIGN1_ANY8H; return ANY8H; }
|
||||
<CHANNEL>".all8h" { yylval->integer = BRW_PREDICATE_ALIGN1_ALL8H; return ALL8H; }
|
||||
<CHANNEL>".any16h" { yylval->integer = BRW_PREDICATE_ALIGN1_ANY16H; return ANY16H; }
|
||||
<CHANNEL>".all16h" { yylval->integer = BRW_PREDICATE_ALIGN1_ALL16H; return ALL16H; }
|
||||
<CHANNEL>".any32h" { yylval->integer = BRW_PREDICATE_ALIGN1_ANY32H; return ANY32H; }
|
||||
<CHANNEL>".all32h" { yylval->integer = BRW_PREDICATE_ALIGN1_ALL32H; return ALL32H; }
|
||||
|
||||
/* Saturation */
|
||||
".sat" { return SATURATE; }
|
||||
|
||||
/* Thread control */
|
||||
atomic { return ATOMIC; }
|
||||
switch { return SWITCH; }
|
||||
|
||||
/* Branch control */
|
||||
BranchCtrl { return BRANCH_CTRL; }
|
||||
|
||||
/* Quarter Control */
|
||||
1[HNQ] { }
|
||||
"2Q" { return QTR_2Q; }
|
||||
"3Q" { return QTR_3Q; }
|
||||
"4Q" { return QTR_4Q; }
|
||||
"2H" { return QTR_2H; }
|
||||
"2N" { return QTR_2N; }
|
||||
"3N" { return QTR_3N; }
|
||||
"4N" { return QTR_4N; }
|
||||
"5N" { return QTR_5N; }
|
||||
"6N" { return QTR_6N; }
|
||||
"7N" { return QTR_7N; }
|
||||
"8N" { return QTR_8N; }
|
||||
|
||||
/* data types */
|
||||
:?B { return TYPE_B; }
|
||||
:?BF { return TYPE_BF; }
|
||||
:?BF8 { return TYPE_BF8; }
|
||||
:?D { return TYPE_D; }
|
||||
:?DF { return TYPE_DF; }
|
||||
:?F { return TYPE_F; }
|
||||
:?HF { return TYPE_HF; }
|
||||
:?HF8 { return TYPE_HF8; }
|
||||
:?Q { return TYPE_Q; }
|
||||
:?UB { return TYPE_UB; }
|
||||
:?UD { return TYPE_UD; }
|
||||
:?UW { return TYPE_UW; }
|
||||
:?UQ { return TYPE_UQ; }
|
||||
:?UV { return TYPE_UV; }
|
||||
:?V { return TYPE_V; }
|
||||
:?VF { return TYPE_VF; }
|
||||
:?W { return TYPE_W; }
|
||||
|
||||
/* Address registers */
|
||||
"a0" { return ADDRREG; }
|
||||
|
||||
/* accumulator registers */
|
||||
"acc"[0-9]+ { yylval->integer = atoi(yytext + 3); return ACCREG; }
|
||||
|
||||
/* channel enable registers */
|
||||
"ce0" { return CHANNELENABLEREG; }
|
||||
|
||||
/* control registers */
|
||||
"cr0" { return CONTROLREG; }
|
||||
|
||||
/* flag registers */
|
||||
"f"[0|1] { BEGIN(CHANNEL); yylval->integer = atoi(yytext + 1); return FLAGREG; }
|
||||
|
||||
/* scalar register */
|
||||
"s0" { return SCALARREG; }
|
||||
|
||||
/* state register */
|
||||
sr[0-9]+ { yylval->integer = atoi(yytext + 2); return STATEREG; }
|
||||
|
||||
/* notification registers */
|
||||
"n0" { BEGIN(REG); return NOTIFYREG; }
|
||||
|
||||
/* IP register */
|
||||
"ip" { return IPREG; }
|
||||
|
||||
/* Thread control register */
|
||||
"tdr0" { return THREADREG; }
|
||||
|
||||
/* performance register */
|
||||
"tm0" { BEGIN(REG); return PERFORMANCEREG; }
|
||||
|
||||
[gr][0-9]+ {
|
||||
yylval->integer = atoi(yytext + 1);
|
||||
BEGIN(REG); return GENREG;
|
||||
}
|
||||
[gr] { return GENREGFILE; }
|
||||
"mask"[0-9]+ { yylval->integer = atoi(yytext + 4); return MASKREG; }
|
||||
|
||||
/* Conditional modifiers */
|
||||
".e" { yylval->integer = BRW_CONDITIONAL_Z; return EQUAL; }
|
||||
".g" { yylval->integer = BRW_CONDITIONAL_G; return GREATER; }
|
||||
".ge" { yylval->integer = BRW_CONDITIONAL_GE; return GREATER_EQUAL; }
|
||||
".l" { yylval->integer = BRW_CONDITIONAL_L; return LESS; }
|
||||
".le" { yylval->integer = BRW_CONDITIONAL_LE; return LESS_EQUAL; }
|
||||
".ne" { yylval->integer = BRW_CONDITIONAL_NZ; return NOT_EQUAL; }
|
||||
".nz" { yylval->integer = BRW_CONDITIONAL_NZ; return NOT_ZERO; }
|
||||
".o" { yylval->integer = BRW_CONDITIONAL_O; return OVERFLOW; }
|
||||
".r" { yylval->integer = BRW_CONDITIONAL_R; return ROUND_INCREMENT; }
|
||||
".u" { yylval->integer = BRW_CONDITIONAL_U; return UNORDERED; }
|
||||
".z" { yylval->integer = BRW_CONDITIONAL_Z; return ZERO; }
|
||||
|
||||
"JIP: " { BEGIN(LABEL); return JIP; }
|
||||
"UIP: " { BEGIN(LABEL); return UIP; }
|
||||
[ \t]+ { }
|
||||
|
||||
"MsgDesc: " { BEGIN(MSGDESC); return MSGDESC_BEGIN; }
|
||||
<MSGDESC>ex_bso { return EX_BSO; }
|
||||
<MSGDESC>src1_len { return SRC1_LEN; }
|
||||
<MSGDESC>"=" { return ASSIGN; }
|
||||
<MSGDESC>[0-9][0-9]* {
|
||||
yylval->integer = strtoul(yytext, NULL, 10);
|
||||
return INTEGER;
|
||||
}
|
||||
<MSGDESC>"{" { yyless(0); BEGIN(INITIAL); return MSGDESC_END; }
|
||||
<MSGDESC>. { }
|
||||
<MSGDESC>\n { yycolumn = 1; }
|
||||
|
||||
"0x"[0-9a-f][0-9a-f]* {
|
||||
yylval->llint = strtoull(yytext + 2, NULL, 16);
|
||||
return LONG;
|
||||
}
|
||||
[0-9][0-9]* {
|
||||
yylval->llint = strtoll(yytext, NULL, 10);
|
||||
return LONG;
|
||||
}
|
||||
|
||||
/* jump label target */
|
||||
[a-zA-Z_][0-9a-zA-Z_]*":" {
|
||||
yylval->string = ralloc_strdup(p->mem_ctx, yytext);
|
||||
/* Stomp the trailing ':' */
|
||||
yylval->string[yyleng - 1] = '\0';
|
||||
return JUMP_LABEL_TARGET;
|
||||
}
|
||||
|
||||
/* jump label */
|
||||
<LABEL>[a-zA-Z_][0-9a-zA-Z_]* {
|
||||
yylval->string = ralloc_strdup(p->mem_ctx, yytext);
|
||||
BEGIN(INITIAL);
|
||||
return JUMP_LABEL;
|
||||
}
|
||||
|
||||
/* SWSB */
|
||||
"@"[1-7] { yylval->integer = atoi(yytext + 1); return REG_DIST_CURRENT; }
|
||||
"F@"[1-7] { yylval->integer = atoi(yytext + 2); return REG_DIST_FLOAT; }
|
||||
"I@"[1-7] { yylval->integer = atoi(yytext + 2); return REG_DIST_INT; }
|
||||
"L@"[1-7] { yylval->integer = atoi(yytext + 2); return REG_DIST_LONG; }
|
||||
"A@"[1-7] { yylval->integer = atoi(yytext + 2); return REG_DIST_ALL; }
|
||||
"M@"[1-7] { yylval->integer = atoi(yytext + 2); return REG_DIST_MATH; }
|
||||
"S@"[1-7] { yylval->integer = atoi(yytext + 2); return REG_DIST_SCALAR; }
|
||||
|
||||
"$"[0-9]* { yylval->integer = atoi(yytext + 1); return SBID_ALLOC; }
|
||||
"$"[0-9]*".src" { yylval->integer = atoi(yytext + 1); return SBID_WAIT_SRC; }
|
||||
"$"[0-9]*".dst" { yylval->integer = atoi(yytext + 1); return SBID_WAIT_DST; }
|
||||
|
||||
/* DPAS params. */
|
||||
"."[1-9][0-9]*x[1-9][0-9]* {
|
||||
yylval->dpas_params.sdepth = atoi(yytext + 1);
|
||||
yylval->dpas_params.rcount = atoi(strchr(yytext, 'x') + 1);
|
||||
return DPAS_PARAMS;
|
||||
}
|
||||
|
||||
\n { yycolumn = 1; }
|
||||
|
||||
. {
|
||||
fprintf(stderr, "%s: %d: %s: at \"%s\"\n",
|
||||
parser->input_filename, brw_asm_get_lineno(yyscanner),
|
||||
"unexpected token", brw_asm_get_text(yyscanner));
|
||||
}
|
||||
%%
|
||||
|
|
@ -806,10 +806,10 @@ namespace {
|
|||
bool progress = false;
|
||||
|
||||
/* BROADCAST is special. It's destination region is a bit of a lie, and
|
||||
* it gets lower in brw_eu_emit. For the purposes of region
|
||||
* restrictions, let's assume that the final code emission will do the
|
||||
* right thing. Doing a bunch of shuffling here is only going to make a
|
||||
* mess of things.
|
||||
* it gets lowered later during code emission. For the purposes of
|
||||
* region restrictions, let's assume that the final code emission will
|
||||
* do the right thing. Doing a bunch of shuffling here is only going to
|
||||
* make a mess of things.
|
||||
*/
|
||||
if (inst->opcode == SHADER_OPCODE_BROADCAST)
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -4,12 +4,90 @@
|
|||
*/
|
||||
|
||||
#include "brw_cfg.h"
|
||||
#include "brw_disasm.h"
|
||||
#include "brw_shader.h"
|
||||
#include "brw_private.h"
|
||||
#include "dev/intel_debug.h"
|
||||
#include "util/half_float.h"
|
||||
|
||||
static const char *
|
||||
conditional_modifier_to_string(unsigned mod)
|
||||
{
|
||||
switch (mod) {
|
||||
case BRW_CONDITIONAL_NONE: return "";
|
||||
case BRW_CONDITIONAL_Z: return ".z";
|
||||
case BRW_CONDITIONAL_NZ: return ".nz";
|
||||
case BRW_CONDITIONAL_G: return ".g";
|
||||
case BRW_CONDITIONAL_GE: return ".ge";
|
||||
case BRW_CONDITIONAL_L: return ".l";
|
||||
case BRW_CONDITIONAL_LE: return ".le";
|
||||
case BRW_CONDITIONAL_R: return ".r";
|
||||
case BRW_CONDITIONAL_O: return ".o";
|
||||
case BRW_CONDITIONAL_U: return ".u";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
brw_lsc_op_to_string(unsigned op)
|
||||
{
|
||||
switch (op) {
|
||||
case LSC_OP_LOAD: return "load";
|
||||
case LSC_OP_LOAD_CMASK: return "load_cmask";
|
||||
case LSC_OP_STORE: return "store";
|
||||
case LSC_OP_STORE_CMASK: return "store_cmask";
|
||||
case LSC_OP_FENCE: return "fence";
|
||||
case LSC_OP_ATOMIC_INC: return "atomic_inc";
|
||||
case LSC_OP_ATOMIC_DEC: return "atomic_dec";
|
||||
case LSC_OP_ATOMIC_LOAD: return "atomic_load";
|
||||
case LSC_OP_ATOMIC_STORE: return "atomic_store";
|
||||
case LSC_OP_ATOMIC_ADD: return "atomic_add";
|
||||
case LSC_OP_ATOMIC_SUB: return "atomic_sub";
|
||||
case LSC_OP_ATOMIC_MIN: return "atomic_min";
|
||||
case LSC_OP_ATOMIC_MAX: return "atomic_max";
|
||||
case LSC_OP_ATOMIC_UMIN: return "atomic_umin";
|
||||
case LSC_OP_ATOMIC_UMAX: return "atomic_umax";
|
||||
case LSC_OP_ATOMIC_CMPXCHG: return "atomic_cmpxchg";
|
||||
case LSC_OP_ATOMIC_FADD: return "atomic_fadd";
|
||||
case LSC_OP_ATOMIC_FSUB: return "atomic_fsub";
|
||||
case LSC_OP_ATOMIC_FMIN: return "atomic_fmin";
|
||||
case LSC_OP_ATOMIC_FMAX: return "atomic_fmax";
|
||||
case LSC_OP_ATOMIC_FCMPXCHG: return "atomic_fcmpxchg";
|
||||
case LSC_OP_ATOMIC_AND: return "atomic_and";
|
||||
case LSC_OP_ATOMIC_OR: return "atomic_or";
|
||||
case LSC_OP_ATOMIC_XOR: return "atomic_xor";
|
||||
case LSC_OP_LOAD_CMASK_MSRT: return "load_cmask_msrt";
|
||||
case LSC_OP_STORE_CMASK_MSRT: return "store_cmask_msrt";
|
||||
default: return "<invalid lsc op>";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
brw_lsc_addr_surftype_to_string(unsigned t)
|
||||
{
|
||||
switch (t) {
|
||||
case LSC_ADDR_SURFTYPE_FLAT: return "flat";
|
||||
case LSC_ADDR_SURFTYPE_BSS: return "bss";
|
||||
case LSC_ADDR_SURFTYPE_SS: return "ss";
|
||||
case LSC_ADDR_SURFTYPE_BTI: return "bti";
|
||||
default: return "<invalid lsc surface>";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
brw_lsc_data_size_to_string(unsigned s)
|
||||
{
|
||||
switch (s) {
|
||||
case LSC_DATA_SIZE_D8: return "d8";
|
||||
case LSC_DATA_SIZE_D16: return "d16";
|
||||
case LSC_DATA_SIZE_D32: return "d32";
|
||||
case LSC_DATA_SIZE_D64: return "d64";
|
||||
case LSC_DATA_SIZE_D8U32: return "d8u32";
|
||||
case LSC_DATA_SIZE_D16U32: return "d16u32";
|
||||
case LSC_DATA_SIZE_D16BF32: return "d16bf32";
|
||||
default: return "<invalid lsc data size>";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
brw_print_instructions(const brw_shader &s, FILE *file)
|
||||
{
|
||||
|
|
@ -326,7 +404,7 @@ brw_print_instruction(const brw_shader &s, const brw_inst *inst, FILE *file, con
|
|||
if (inst->saturate)
|
||||
fprintf(file, ".sat");
|
||||
if (inst->conditional_mod) {
|
||||
fprintf(file, "%s", conditional_modifier[inst->conditional_mod]);
|
||||
fprintf(file, "%s", conditional_modifier_to_string(inst->conditional_mod));
|
||||
if (!inst->predicate &&
|
||||
(inst->opcode != BRW_OPCODE_SEL &&
|
||||
inst->opcode != BRW_OPCODE_CSEL &&
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@
|
|||
* This file defines struct brw_reg, which is our representation for EU
|
||||
* registers. They're not a hardware specific format, just an abstraction
|
||||
* that intends to capture the full flexibility of the hardware registers.
|
||||
*
|
||||
* The brw_eu_emit.c layer's brw_set_dest/brw_set_src[01] functions encode
|
||||
* the abstract brw_reg type into the actual hardware instruction encoding.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@
|
|||
#include <vector>
|
||||
|
||||
#include "brw_eu.h"
|
||||
#include "brw_disasm_info.h"
|
||||
#include "brw_shader.h"
|
||||
#include "brw_cfg.h"
|
||||
#include "dev/intel_debug.h"
|
||||
|
|
@ -239,20 +238,6 @@ brw_opcode_to_gen(enum opcode op)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
brw_swsb_encode(const struct intel_device_info *devinfo,
|
||||
gen_swsb swsb, enum opcode op)
|
||||
{
|
||||
return gen_swsb_encode(devinfo, swsb, brw_opcode_to_gen(op));
|
||||
}
|
||||
|
||||
gen_swsb
|
||||
brw_swsb_decode(const struct intel_device_info *devinfo,
|
||||
bool is_unordered, uint32_t raw, enum opcode op)
|
||||
{
|
||||
return gen_swsb_decode(devinfo, is_unordered, raw, brw_opcode_to_gen(op));
|
||||
}
|
||||
|
||||
gen_opcode
|
||||
brw_generator::to_gen(enum opcode op)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,19 +23,10 @@ libintel_compiler_brw_files = files(
|
|||
'brw_compile_vs.cpp',
|
||||
'brw_compiler.c',
|
||||
'brw_compiler.h',
|
||||
'brw_disasm.c',
|
||||
'brw_disasm_info.cpp',
|
||||
'brw_disasm_info.h',
|
||||
'brw_eu.c',
|
||||
'brw_eu_compact.c',
|
||||
'brw_eu_defines.h',
|
||||
'brw_eu_emit.c',
|
||||
'brw_eu_inst.h',
|
||||
'brw_eu.h',
|
||||
'brw_eu_validate.c',
|
||||
'brw_from_nir.cpp',
|
||||
'brw_generator.cpp',
|
||||
'brw_generator.h',
|
||||
'brw_inst.cpp',
|
||||
'brw_inst.h',
|
||||
'brw_isa_info.h',
|
||||
|
|
@ -164,8 +155,6 @@ if with_tests
|
|||
'intel_compiler_brw_tests',
|
||||
files(
|
||||
'test_def_analysis.cpp',
|
||||
'test_eu_compact.cpp',
|
||||
'test_eu_validate.cpp',
|
||||
'test_helpers.cpp',
|
||||
'test_helpers.h',
|
||||
'test_insert_load_reg.cpp',
|
||||
|
|
@ -194,52 +183,6 @@ endif
|
|||
|
||||
if with_intel_tools
|
||||
|
||||
brw_gram_tab = custom_target(
|
||||
'brw_gram.tab.[ch]',
|
||||
input : 'brw_gram.y',
|
||||
output : ['brw_gram.tab.c', 'brw_gram.tab.h'],
|
||||
command : bison_command
|
||||
)
|
||||
|
||||
brw_lex_yy_c = custom_target(
|
||||
'brw_lex.yy.c',
|
||||
input : 'brw_lex.l',
|
||||
output : 'brw_lex.yy.c',
|
||||
command : [prog_flex, '-o', '@OUTPUT@', '@INPUT@']
|
||||
)
|
||||
|
||||
brw_asm_deps = [
|
||||
dep_thread,
|
||||
idep_intel_compiler_brw,
|
||||
idep_intel_dev,
|
||||
idep_mesautil,
|
||||
]
|
||||
|
||||
brw_asm = static_library(
|
||||
'brw_asm',
|
||||
['brw_asm.c', brw_gram_tab[0], brw_gram_tab[1], brw_lex_yy_c],
|
||||
dependencies : brw_asm_deps,
|
||||
include_directories : [inc_include, inc_src, inc_intel],
|
||||
c_args : [no_override_init_args, soong_compat_c_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
build_by_default : false,
|
||||
)
|
||||
|
||||
idep_brw_asm = declare_dependency(
|
||||
link_with : brw_asm,
|
||||
dependencies : brw_asm_deps,
|
||||
)
|
||||
|
||||
brw_asm_tool = executable(
|
||||
'brw_asm',
|
||||
['brw_asm_tool.c'],
|
||||
dependencies : idep_brw_asm,
|
||||
include_directories : [inc_include, inc_src, inc_intel],
|
||||
c_args : [no_override_init_args, soong_compat_c_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
install : true
|
||||
)
|
||||
|
||||
asm_testcases = [
|
||||
['skl', 'gfx9'],
|
||||
['icl', 'gfx11'],
|
||||
|
|
@ -264,15 +207,4 @@ foreach testcase : asm_testcases
|
|||
)
|
||||
endforeach
|
||||
|
||||
brw_disasm_tool = executable(
|
||||
'brw_disasm',
|
||||
files('brw_disasm_tool.c'),
|
||||
dependencies : [idep_mesautil, dep_thread, idep_intel_dev,
|
||||
idep_intel_compiler_brw],
|
||||
include_directories : [inc_include, inc_src, inc_intel],
|
||||
c_args : [no_override_init_args, soong_compat_c_args],
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
install : true
|
||||
)
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -1,272 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2012 Intel Corporation
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include "util/ralloc.h"
|
||||
#include "brw_disasm.h"
|
||||
#include "brw_eu.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
struct CompactParams {
|
||||
unsigned verx10;
|
||||
unsigned align;
|
||||
};
|
||||
|
||||
std::string
|
||||
get_compact_params_name(const testing::TestParamInfo<CompactParams> p)
|
||||
{
|
||||
CompactParams params = p.param;
|
||||
std::stringstream ss;
|
||||
ss << params.verx10 << "_";
|
||||
switch (params.align) {
|
||||
case BRW_ALIGN_1:
|
||||
ss << "Align_1";
|
||||
break;
|
||||
case BRW_ALIGN_16:
|
||||
ss << "Align_16";
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE("invalid align");
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static bool
|
||||
test_compact_instruction(struct brw_codegen *p, brw_eu_inst src)
|
||||
{
|
||||
brw_eu_compact_inst dst;
|
||||
memset(&dst, 0xd0, sizeof(dst));
|
||||
|
||||
if (brw_try_compact_instruction(p->isa, &dst, &src)) {
|
||||
brw_eu_inst uncompacted;
|
||||
|
||||
brw_uncompact_instruction(p->isa, &uncompacted, &dst);
|
||||
if (memcmp(&uncompacted, &src, sizeof(src))) {
|
||||
brw_debug_compact_uncompact(p->isa, &src, &uncompacted);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
brw_eu_compact_inst unchanged;
|
||||
memset(&unchanged, 0xd0, sizeof(unchanged));
|
||||
/* It's not supposed to change dst unless it compacted. */
|
||||
if (memcmp(&unchanged, &dst, sizeof(dst))) {
|
||||
fprintf(stderr, "Failed to compact, but dst changed\n");
|
||||
fprintf(stderr, " Instruction: ");
|
||||
brw_disassemble_inst(stderr, p->isa, &src, false, 0, NULL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When doing fuzz testing, pad bits won't round-trip.
|
||||
*
|
||||
* This sort of a superset of skip_bit, which is testing for changing bits that
|
||||
* aren't worth testing for fuzzing. We also just want to clear bits that
|
||||
* become meaningless once fuzzing twiddles a related bit.
|
||||
*/
|
||||
static void
|
||||
clear_pad_bits(const struct brw_isa_info *isa, brw_eu_inst *inst)
|
||||
{
|
||||
const struct intel_device_info *devinfo = isa->devinfo;
|
||||
|
||||
if (brw_eu_inst_opcode(isa, inst) != BRW_OPCODE_SEND &&
|
||||
brw_eu_inst_opcode(isa, inst) != BRW_OPCODE_SENDC &&
|
||||
brw_eu_inst_src0_reg_file(devinfo, inst) != IMM &&
|
||||
brw_eu_inst_src1_reg_file(devinfo, inst) != IMM) {
|
||||
brw_eu_inst_set_bits(inst, 127, 111, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
skip_bit(const struct brw_isa_info *isa, brw_eu_inst *src, int bit)
|
||||
{
|
||||
const struct intel_device_info *devinfo = isa->devinfo;
|
||||
|
||||
/* pad bit */
|
||||
if (bit == 7)
|
||||
return true;
|
||||
|
||||
/* The compact bit -- uncompacted can't have it set. */
|
||||
if (bit == 29)
|
||||
return true;
|
||||
|
||||
if (is_3src(isa, brw_eu_inst_opcode(isa, src))) {
|
||||
if (bit == 127)
|
||||
return true;
|
||||
} else {
|
||||
if (bit == 47)
|
||||
return true;
|
||||
|
||||
if (bit == 11)
|
||||
return true;
|
||||
|
||||
if (bit == 95)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* sometimes these are pad bits. */
|
||||
if (brw_eu_inst_opcode(isa, src) != BRW_OPCODE_SEND &&
|
||||
brw_eu_inst_opcode(isa, src) != BRW_OPCODE_SENDC &&
|
||||
brw_eu_inst_src0_reg_file(devinfo, src) != IMM &&
|
||||
brw_eu_inst_src1_reg_file(devinfo, src) != IMM &&
|
||||
bit >= 121) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
test_fuzz_compact_instruction(struct brw_codegen *p, brw_eu_inst src)
|
||||
{
|
||||
for (int bit0 = 0; bit0 < 128; bit0++) {
|
||||
if (skip_bit(p->isa, &src, bit0))
|
||||
continue;
|
||||
|
||||
for (int bit1 = 0; bit1 < 128; bit1++) {
|
||||
brw_eu_inst instr = src;
|
||||
uint64_t *bits = instr.data;
|
||||
|
||||
if (skip_bit(p->isa, &src, bit1))
|
||||
continue;
|
||||
|
||||
bits[bit0 / 64] ^= (1ull << (bit0 & 63));
|
||||
bits[bit1 / 64] ^= (1ull << (bit1 & 63));
|
||||
|
||||
clear_pad_bits(p->isa, &instr);
|
||||
|
||||
if (!brw_validate_instruction(p->isa, &instr, 0, sizeof(brw_eu_inst), NULL))
|
||||
continue;
|
||||
|
||||
if (!test_compact_instruction(p, instr)) {
|
||||
printf(" twiddled bits for fuzzing %d, %d\n", bit0, bit1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class CompactTestFixture : public testing::TestWithParam<CompactParams> {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
CompactParams params = GetParam();
|
||||
mem_ctx = ralloc_context(NULL);
|
||||
devinfo = rzalloc(mem_ctx, intel_device_info);
|
||||
p = rzalloc(mem_ctx, brw_codegen);
|
||||
|
||||
devinfo->verx10 = params.verx10;
|
||||
devinfo->ver = devinfo->verx10 / 10;
|
||||
|
||||
brw_init_isa_info(&isa, devinfo);
|
||||
brw_init_codegen(&isa, p, p);
|
||||
brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
|
||||
brw_set_default_access_mode(p, params.align);
|
||||
};
|
||||
|
||||
virtual void TearDown() {
|
||||
EXPECT_EQ(p->nr_insn, 1);
|
||||
EXPECT_TRUE(test_compact_instruction(p, p->store[0]));
|
||||
EXPECT_TRUE(test_fuzz_compact_instruction(p, p->store[0]));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
};
|
||||
|
||||
void *mem_ctx;
|
||||
struct brw_isa_info isa;
|
||||
intel_device_info *devinfo;
|
||||
brw_codegen *p;
|
||||
};
|
||||
|
||||
class Instructions : public CompactTestFixture {};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
CompactTest,
|
||||
Instructions,
|
||||
testing::Values(
|
||||
CompactParams{ 90, BRW_ALIGN_1 }, CompactParams{ 90, BRW_ALIGN_16 },
|
||||
CompactParams{ 110, BRW_ALIGN_1 },
|
||||
CompactParams{ 120, BRW_ALIGN_1 },
|
||||
CompactParams{ 125, BRW_ALIGN_1 },
|
||||
CompactParams{ 200, BRW_ALIGN_1 },
|
||||
CompactParams{ 300, BRW_ALIGN_1 }
|
||||
),
|
||||
get_compact_params_name);
|
||||
|
||||
TEST_P(Instructions, ADD_GRF_GRF_GRF)
|
||||
{
|
||||
struct brw_reg g0 = brw_vec8_grf(0, 0);
|
||||
struct brw_reg g2 = brw_vec8_grf(2, 0);
|
||||
struct brw_reg g4 = brw_vec8_grf(4, 0);
|
||||
|
||||
brw_ADD(p, g0, g2, g4);
|
||||
}
|
||||
|
||||
TEST_P(Instructions, ADD_GRF_GRF_IMM)
|
||||
{
|
||||
struct brw_reg g0 = brw_vec8_grf(0, 0);
|
||||
struct brw_reg g2 = brw_vec8_grf(2, 0);
|
||||
|
||||
brw_ADD(p, g0, g2, brw_imm_f(1.0));
|
||||
}
|
||||
|
||||
TEST_P(Instructions, ADD_GRF_GRF_IMM_d)
|
||||
{
|
||||
struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_TYPE_D);
|
||||
struct brw_reg g2 = retype(brw_vec8_grf(2, 0), BRW_TYPE_D);
|
||||
|
||||
brw_ADD(p, g0, g2, brw_imm_d(1));
|
||||
}
|
||||
|
||||
TEST_P(Instructions, MOV_GRF_GRF)
|
||||
{
|
||||
struct brw_reg g0 = brw_vec8_grf(0, 0);
|
||||
struct brw_reg g2 = brw_vec8_grf(2, 0);
|
||||
|
||||
brw_MOV(p, g0, g2);
|
||||
}
|
||||
|
||||
TEST_P(Instructions, ADD_vec1_GRF_GRF_GRF)
|
||||
{
|
||||
struct brw_reg g0 = brw_vec1_grf(0, 0);
|
||||
struct brw_reg g2 = brw_vec1_grf(2, 0);
|
||||
struct brw_reg g4 = brw_vec1_grf(4, 0);
|
||||
|
||||
brw_ADD(p, g0, g2, g4);
|
||||
}
|
||||
|
||||
TEST_P(Instructions, f0_0_MOV_GRF_GRF)
|
||||
{
|
||||
struct brw_reg g0 = brw_vec8_grf(0, 0);
|
||||
struct brw_reg g2 = brw_vec8_grf(2, 0);
|
||||
|
||||
brw_push_insn_state(p);
|
||||
brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL);
|
||||
brw_MOV(p, g0, g2);
|
||||
brw_pop_insn_state(p);
|
||||
}
|
||||
|
||||
/* The handling of f0.1 vs f0.0 changes between gfx6 and gfx7. Explicitly test
|
||||
* it, so that we run the fuzzing can run over all the other bits that might
|
||||
* interact with it.
|
||||
*/
|
||||
TEST_P(Instructions, f0_1_MOV_GRF_GRF)
|
||||
{
|
||||
struct brw_reg g0 = brw_vec8_grf(0, 0);
|
||||
struct brw_reg g2 = brw_vec8_grf(2, 0);
|
||||
|
||||
brw_push_insn_state(p);
|
||||
brw_set_default_predicate_control(p, BRW_PREDICATE_NORMAL);
|
||||
brw_eu_inst *mov = brw_MOV(p, g0, g2);
|
||||
brw_eu_inst_set_flag_subreg_nr(p->devinfo, mov, 1);
|
||||
brw_pop_insn_state(p);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue