Unverified Commit 70308a5a authored by Sagar Ghuge's avatar Sagar Ghuge Committed by Matt Turner

intel/tools: New i965 instruction assembler tool

Tool is inspired from igt's assembler tool. Thanks to Matt Turner, who
mentored me through out this project.

v2: Fix memory leaks and naming convention (Caio)
v3: Fix meson changes (Dylan Baker)
v4: Fix usage options (Matt Turner)
Signed-off-by: Sagar Ghuge's avatarSagar Ghuge <sagar.ghuge@intel.com>
Reviewed-by: Dylan Baker's avatarDylan Baker <dylan@pnwbakers.com>
Reviewed-by: Matt Turner's avatarMatt Turner <mattst88@gmail.com>
Closes: mesa/mesa!141
parent a232aa5c
/*
* Copyright © 2018 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#include <stdio.h>
#include <getopt.h>
#include "i965_asm.h"
extern FILE *yyin;
struct brw_codegen *p;
static int c_literal_output = 0;
char *input_filename;
int errors;
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"
" -l, --c-literal C literal\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"
" i965_asm -g kbl input.asm -o output\n",
progname);
}
static void
print_instruction(FILE *output, bool compact, const brw_inst *instruction)
{
int byte_limit;
byte_limit = (compact == true) ? 8 : 16;
if (c_literal_output) {
fprintf(output, "\t0x%02x,", ((unsigned char *)instruction)[0]);
for (unsigned i = 1; i < byte_limit; i++)
fprintf(output, " 0x%02x,", ((unsigned char *)instruction)[i]);
} else {
fprintf(output, "%02x", ((unsigned char *)instruction)[0]);
for (unsigned i = 1; i < byte_limit; i++)
fprintf(output, " %02x", ((unsigned char *)instruction)[i]);
}
fprintf(output, "\n");
}
static struct gen_device_info *
i965_disasm_init(uint16_t pci_id)
{
struct gen_device_info *devinfo;
devinfo = malloc(sizeof *devinfo);
if (devinfo == NULL)
return NULL;
if (!gen_get_device_info(pci_id, devinfo)) {
fprintf(stderr, "can't find device information: pci_id=0x%x\n",
pci_id);
return NULL;
}
brw_init_compaction_tables(devinfo);
return devinfo;
}
int main(int argc, char **argv)
{
char *output_file = NULL;
char c;
FILE *output = stdout;
bool help = false, compact = false;
void *store;
uint64_t pci_id = 0;
int offset, err;
int start_offset = 0;
struct disasm_info *disasm_info;
struct gen_device_info *devinfo;
int result = EXIT_FAILURE;
const struct option i965_asm_opts[] = {
{ "help", no_argument, (int *) &help, true },
{ "c-literal", no_argument, NULL, 'c' },
{ "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, ":g:o:lh", i965_asm_opts, NULL)) != -1) {
switch (c) {
case 'g': {
const int id = gen_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 'l':
c_literal_output = 1;
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 (!argv[optind]) {
fprintf(stderr, "Please specify input file\n");
goto end;
}
input_filename = strdup(argv[optind]);
yyin = fopen(input_filename, "r");
if (!yyin) {
fprintf(stderr, "Unable to read input file : %s\n",
input_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_disasm_init(pci_id);
if (!devinfo) {
fprintf(stderr, "Unable to allocate memory for "
"gen_device_info struct instance.\n");
goto end;
}
p = rzalloc(NULL, struct brw_codegen);
brw_init_codegen(devinfo, p, p);
p->automatic_exec_sizes = false;
err = yyparse();
if (err || errors)
goto end;
store = p->store;
disasm_info = disasm_initialize(p->devinfo, NULL);
if (!disasm_info) {
fprintf(stderr, "Unable to initialize disasm_info struct instance\n");
goto end;
}
if (c_literal_output)
fprintf(output, "static const char gen_eu_bytes[] = {\n");
brw_validate_instructions(p->devinfo, p->store, 0,
p->next_insn_offset, disasm_info);
int nr_insn = (p->next_insn_offset - start_offset) / 16;
if (compact)
brw_compact_instructions(p, start_offset, disasm_info);
ralloc_free(disasm_info);
for (int i = 0; i < nr_insn; i++) {
const brw_inst *insn = store + offset;
bool compacted = false;
if (compact && brw_inst_cmpt_control(p->devinfo, insn)) {
offset += 8;
compacted = true;
} else {
offset += 16;
}
print_instruction(output, compacted, insn);
}
if (c_literal_output)
fprintf(output, "}");
result = EXIT_SUCCESS;
goto end;
end:
if (input_filename)
free(input_filename);
if (output_file)
free(output_file);
if (yyin)
fclose(yyin);
if (output)
fclose(output);
if (p)
ralloc_free(p);
if (devinfo)
free(devinfo);
exit(result);
}
/*
* Copyright © 2018 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#ifndef __I965_ASM_H__
#define __I965_ASM_H__
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include "compiler/brw_reg.h"
#include "compiler/brw_reg_type.h"
#include "compiler/brw_eu_defines.h"
#include "compiler/brw_inst.h"
#include "compiler/brw_eu.h"
#include "dev/gen_device_info.h"
void yyerror (char *);
int yyparse(void);
int yylex(void);
char *lex_text(void);
extern struct brw_codegen *p;
extern int errors;
extern char *input_filename;
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;
};
struct options {
unsigned access_mode:1;
unsigned compression_control:2;
unsigned thread_control:2;
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 qtr_ctrl:2;
unsigned nib_ctrl:1;
unsigned is_compr:1;
};
#endif /* __I965_ASM_H__ */
This diff is collapsed.
This diff is collapsed.
......@@ -127,3 +127,29 @@ if with_tools.contains('intel-ui')
install : true
)
endif
i965_gram_tab = custom_target(
'i965_gram.tab.[ch]',
input : 'i965_gram.y',
output : ['i965_gram.tab.c', 'i965_gram.tab.h'],
command : [
prog_bison, '@INPUT@', '--defines=@OUTPUT1@',
'--output=@OUTPUT0@'
]
)
i965_lex_yy_c = custom_target(
'i965_lex.yy.c',
input : 'i965_lex.l',
output : 'i965_lex.yy.c',
command : [prog_flex, '-o', '@OUTPUT@', '@INPUT@']
)
i965_asm = executable(
'i965_asm',
['i965_asm.c', i965_gram_tab[0], i965_gram_tab[1], i965_lex_yy_c],
include_directories : [inc_common, inc_intel],
link_with : [libintel_common, libintel_compiler, libintel_dev, libmesa_util],
c_args : [c_vis_args, no_override_init_args],
install : true
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment