mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-11 01:46:14 +00:00
Support instructions which strictly follow the documents.
Previously some instructions parsed by this assembler don't follow the documents. Signed-off-by: Chen, Yangyang <yangyang.chen@intel.com> Signed-off-by: Han, Haofu <haofu.han@intel.com> Signed-off-by: Zou Nan hai <nanhai.zou@intel.com> Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
This commit is contained in:
parent
66649d7b4e
commit
27b4303a30
@ -18,5 +18,6 @@ gram.h: gram.c
|
||||
|
||||
BUILT_SOURCES = gram.h gram.c lex.c
|
||||
MAINTAINERCLEANFILES = $(BUILT_SOURCES)
|
||||
LEX = flex -i
|
||||
|
||||
# man_MANS = intel-gen4asm.1
|
||||
|
@ -848,6 +848,7 @@
|
||||
#define R02_PRIM_END 0x1
|
||||
#define R02_PRIM_START 0x2
|
||||
|
||||
|
||||
#define EX_DESC_SFID_MASK 0xF
|
||||
#define EX_DESC_EOT_MASK 0x20
|
||||
|
||||
#endif
|
||||
|
@ -1193,7 +1193,11 @@ struct brw_instruction
|
||||
GLuint pad1:1;
|
||||
GLuint sfid:4;
|
||||
} send_gen5; /* for GEN5 only */
|
||||
|
||||
struct
|
||||
{
|
||||
GLuint pad:26;
|
||||
GLuint msg_ext:6;
|
||||
} msg_ext;
|
||||
} bits2;
|
||||
|
||||
union
|
||||
|
@ -34,6 +34,7 @@ typedef unsigned int GLuint;
|
||||
typedef int GLint;
|
||||
typedef float GLfloat;
|
||||
|
||||
#include "brw_defines.h"
|
||||
#include "brw_structs.h"
|
||||
|
||||
void yyerror (char *msg);
|
||||
@ -46,6 +47,19 @@ struct direct_reg {
|
||||
int reg_file, reg_nr, subreg_nr;
|
||||
};
|
||||
|
||||
struct condition {
|
||||
int cond;
|
||||
int flagreg;
|
||||
};
|
||||
|
||||
struct region {
|
||||
int vert_stride, width, horiz_stride;
|
||||
int is_default;
|
||||
};
|
||||
struct regtype {
|
||||
int type;
|
||||
int is_default;
|
||||
};
|
||||
/**
|
||||
* This structure is the internal representation of register-indirect addressed
|
||||
* registers in the parser.
|
||||
@ -83,6 +97,7 @@ struct src_operand {
|
||||
int abs, negate;
|
||||
|
||||
int horiz_stride, width, vert_stride;
|
||||
int default_region;
|
||||
|
||||
int address_mode; /* 0 if direct, 1 if register-indirect */
|
||||
int address_subreg_nr;
|
||||
@ -101,6 +116,7 @@ typedef struct {
|
||||
union {
|
||||
uint32_t d;
|
||||
float f;
|
||||
int32_t signed_d;
|
||||
} u;
|
||||
} imm32_t;
|
||||
|
||||
@ -127,6 +143,40 @@ struct brw_program {
|
||||
|
||||
extern struct brw_program compiled_program;
|
||||
|
||||
#define TYPE_B_INDEX 0
|
||||
#define TYPE_UB_INDEX 1
|
||||
#define TYPE_W_INDEX 2
|
||||
#define TYPE_UW_INDEX 3
|
||||
#define TYPE_D_INDEX 4
|
||||
#define TYPE_UD_INDEX 5
|
||||
#define TYPE_F_INDEX 6
|
||||
|
||||
#define TOTAL_TYPES 7
|
||||
|
||||
struct program_defaults {
|
||||
int execute_size;
|
||||
int execute_type[TOTAL_TYPES];
|
||||
int register_type;
|
||||
int register_type_regfile;
|
||||
struct region source_region;
|
||||
struct region source_region_type[TOTAL_TYPES];
|
||||
struct region dest_region;
|
||||
struct region dest_region_type[TOTAL_TYPES];
|
||||
};
|
||||
extern struct program_defaults program_defaults;
|
||||
|
||||
struct declared_register {
|
||||
char *name;
|
||||
struct direct_reg base;
|
||||
int element_size;
|
||||
struct region src_region;
|
||||
int dst_region;
|
||||
int type;
|
||||
struct declared_register *next;
|
||||
};
|
||||
struct declared_register *find_register(char *name);
|
||||
void insert_register(struct declared_register *reg);
|
||||
|
||||
int yyparse(void);
|
||||
int yylex(void);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
int saved_state = 0;
|
||||
extern char *input_filename;
|
||||
extern long int gen_level;
|
||||
|
||||
%}
|
||||
%x BLOCK_COMMENT
|
||||
%x CHANNEL
|
||||
@ -17,6 +18,10 @@ extern long int gen_level;
|
||||
|
||||
%%
|
||||
\/\/.*[\r\n] { } /* eat up single-line comments */
|
||||
"\.kernel".*[\r\n] { }
|
||||
"\.end_kernel".*[\r\n] { }
|
||||
"\.code".*[\r\n] { }
|
||||
"\.end_code".*[\r\n] { }
|
||||
|
||||
/* eat up multi-line comments, non-nesting. */
|
||||
\/\* {
|
||||
@ -57,7 +62,7 @@ extern long int gen_level;
|
||||
return Z;
|
||||
}
|
||||
<CHANNEL>"w" {
|
||||
yylval.integer = BRW_CHANNEL_W;
|
||||
yylval.integer = BRW_CHANNEL_W;
|
||||
return W;
|
||||
}
|
||||
<CHANNEL>. {
|
||||
@ -154,6 +159,7 @@ extern long int gen_level;
|
||||
"*" { return MULTIPLY;}
|
||||
"/" { return DIVIDE; }
|
||||
":" { return COLON; }
|
||||
"=" { return EQ; }
|
||||
"(abs)" { return ABS; }
|
||||
|
||||
/* Most register accesses are lexed as REGFILE[0-9]+, to prevent the register
|
||||
@ -166,7 +172,7 @@ extern long int gen_level;
|
||||
* like g[a#.#] or m[a#.#].
|
||||
*/
|
||||
"acc"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
yylval.integer = atoi(yytext + 3);
|
||||
return ACCREG;
|
||||
}
|
||||
"a"[0-9]+ {
|
||||
@ -181,17 +187,23 @@ extern long int gen_level;
|
||||
return MSGREGFILE;
|
||||
}
|
||||
"mask"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
yylval.integer = atoi(yytext + 4);
|
||||
return MASKREG;
|
||||
}
|
||||
"ms"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
yylval.integer = atoi(yytext + 2);
|
||||
return MASKSTACKREG;
|
||||
}
|
||||
"msd"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
yylval.integer = atoi(yytext + 3);
|
||||
return MASKSTACKDEPTHREG;
|
||||
}
|
||||
|
||||
"n0."[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 3);
|
||||
return NOTIFYREG;
|
||||
}
|
||||
|
||||
"n"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
return NOTIFYREG;
|
||||
@ -216,11 +228,11 @@ extern long int gen_level;
|
||||
return GENREGFILE;
|
||||
}
|
||||
"cr"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
yylval.integer = atoi(yytext + 2);
|
||||
return CONTROLREG;
|
||||
}
|
||||
"sr"[0-9]+ {
|
||||
yylval.integer = atoi(yytext + 1);
|
||||
yylval.integer = atoi(yytext + 2);
|
||||
return STATEREG;
|
||||
}
|
||||
"ip" {
|
||||
@ -276,13 +288,29 @@ extern long int gen_level;
|
||||
"B" { return TYPE_B; }
|
||||
":B" { return TYPE_B; }
|
||||
"F" { return TYPE_F; }
|
||||
":F" { return TYPE_B; }
|
||||
":F" { return TYPE_F; }
|
||||
"VF" {return TYPE_VF; }
|
||||
":VF" {return TYPE_VF; }
|
||||
"V" { return TYPE_V; }
|
||||
":V" { return TYPE_V; }
|
||||
|
||||
"sat" { return SATURATE; }
|
||||
#".kernel" { return KERNEL_PRAGMA;}
|
||||
#".end_kernel" { return END_KERNEL_PRAGMA;}
|
||||
#".code" { return CODE_PRAGMA;}
|
||||
#".end_code" { return END_CODE_PRAGMA;}
|
||||
".reg_count_payload" { return REG_COUNT_PAYLOAD_PRAGMA; }
|
||||
".reg_count_total" { return REG_COUNT_TOTAL_PRAGMA; }
|
||||
".default_execution_size" { return DEFAULT_EXEC_SIZE_PRAGMA; }
|
||||
".default_register_type" { return DEFAULT_REG_TYPE_PRAGMA; }
|
||||
".declare" { return DECLARE_PRAGMA; }
|
||||
"Base" { return BASE; }
|
||||
"ElementSize" { return ELEMENTSIZE; }
|
||||
"SrcRegion" { return SRCREGION; }
|
||||
"DstRegion" { return DSTREGION; }
|
||||
"Type" { return TYPE; }
|
||||
|
||||
|
||||
".sat" { return SATURATE; }
|
||||
"align1" { return ALIGN1; }
|
||||
"align16" { return ALIGN16; }
|
||||
"sechalf" { return SECHALF; }
|
||||
|
@ -39,32 +39,150 @@ extern FILE *yyin;
|
||||
extern int errors;
|
||||
|
||||
long int gen_level = 4;
|
||||
int advanced_flag = 0; /* 0: in unit of type, 1: in unit of data element size */
|
||||
int need_export = 0;
|
||||
char *input_filename = "<stdin>";
|
||||
char *export_filename = NULL;
|
||||
|
||||
struct brw_program compiled_program;
|
||||
struct program_defaults program_defaults;
|
||||
|
||||
|
||||
#define HASHSZ 37
|
||||
static struct declared_register *declared_register_table[HASHSZ];
|
||||
|
||||
static const struct option longopts[] = {
|
||||
{"advanced", no_argument, 0, 'a'},
|
||||
{"export", required_argument, 0, 'e'},
|
||||
{"input_list", required_argument, 0, 'l'},
|
||||
{"output", required_argument, 0, 'o'},
|
||||
{"gen", required_argument, 0, 'g'},
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: intel-gen4asm [-o outputfile] [-g <4|5|6>] inputfile\n");
|
||||
fprintf(stderr, "usage: intel-gen4asm [options] inputfile\n");
|
||||
fprintf(stderr, "OPTIONS:\n");
|
||||
fprintf(stderr, "\t-a, --advanced Set advanced flag\n");
|
||||
fprintf(stderr, "\t-e, --export {exportfile} Export label file\n");
|
||||
fprintf(stderr, "\t-l, --input_list {entrytablefile} Input entry_table_list file\n");
|
||||
fprintf(stderr, "\t-o, --output {outputfile} Specify output file\n");
|
||||
fprintf(stderr, "\t-g, --gen <4|5|6> Specify GPU generation\n");
|
||||
}
|
||||
|
||||
static int hash(char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
while(*name)
|
||||
ret += *name++;
|
||||
return ret%HASHSZ;
|
||||
}
|
||||
|
||||
struct declared_register *find_register(char *name)
|
||||
{
|
||||
int index = hash(name);
|
||||
struct declared_register *reg;
|
||||
for (reg = declared_register_table[index];reg; reg = reg->next)
|
||||
if (strcasecmp(reg->name,name) == 0)
|
||||
return reg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void insert_register(struct declared_register *reg)
|
||||
{
|
||||
int index = hash(reg->name);
|
||||
reg->next = declared_register_table[index];
|
||||
declared_register_table[index] = reg;
|
||||
}
|
||||
|
||||
static void free_register_table(void)
|
||||
{
|
||||
struct declared_register *reg, *next;
|
||||
int i;
|
||||
for (i = 0; i < HASHSZ; i++) {
|
||||
reg = declared_register_table[i];
|
||||
while(reg) {
|
||||
next = reg->next;
|
||||
free(reg->name);
|
||||
free(reg);
|
||||
reg = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char **entry_point_table = NULL;
|
||||
int entry_point_table_length = 0;
|
||||
|
||||
#define DEFAULTBUFSIZE 800
|
||||
static int read_entry_file(char *fn)
|
||||
{
|
||||
FILE *entry_table_file;
|
||||
char buf[DEFAULTBUFSIZE];
|
||||
char *ptr;
|
||||
int curr_table_length = 80;
|
||||
if (!fn) {
|
||||
return 0;
|
||||
}
|
||||
if ((entry_point_table =
|
||||
malloc(curr_table_length*sizeof(char*))) == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
entry_table_file = fopen(fn, "r");
|
||||
if (!entry_table_file) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int size = DEFAULTBUFSIZE;
|
||||
if((ptr = fgets(buf, size, entry_table_file))==NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
if(entry_point_table_length == curr_table_length)
|
||||
{
|
||||
if ((entry_point_table = realloc(entry_point_table,
|
||||
curr_table_length*2*sizeof(char*))) == NULL) {
|
||||
return 1;
|
||||
}
|
||||
curr_table_length *= 2;
|
||||
}
|
||||
entry_point_table[entry_point_table_length] = strdup(buf);
|
||||
entry_point_table_length ++;
|
||||
|
||||
}
|
||||
fclose(entry_table_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_entry_point(char *s)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < entry_point_table_length; i++) {
|
||||
if (strcmp(entry_point_table[i], s) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *output_file = NULL;
|
||||
char *entry_table_file = NULL;
|
||||
FILE *output = stdout;
|
||||
struct brw_program_instruction *entry, *entry1;
|
||||
FILE *export_file;
|
||||
struct brw_program_instruction *entry, *entry1, *tmp_entry;
|
||||
int err, inst_offset;
|
||||
char o;
|
||||
|
||||
while ((o = getopt_long(argc, argv, "o:g:", longopts, NULL)) != -1) {
|
||||
while ((o = getopt_long(argc, argv, "e:l:o:g:a", longopts, NULL)) != -1) {
|
||||
switch (o) {
|
||||
case 'o':
|
||||
if (strcmp(optarg, "-") != 0)
|
||||
output_file = optarg;
|
||||
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
@ -77,6 +195,21 @@ int main(int argc, char **argv)
|
||||
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
advanced_flag = 1;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
need_export = 1;
|
||||
if (strcmp(optarg, "-") != 0)
|
||||
export_filename = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (strcmp(optarg, "-") != 0)
|
||||
entry_table_file = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
@ -98,6 +231,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
program_defaults.register_type = BRW_REGISTER_TYPE_F;
|
||||
|
||||
err = yyparse();
|
||||
|
||||
if (err || errors)
|
||||
@ -109,35 +244,71 @@ int main(int argc, char **argv)
|
||||
perror("Couldn't open output file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (read_entry_file(entry_table_file)) {
|
||||
fprintf(stderr, "Read entry file error\n");
|
||||
exit(1);
|
||||
}
|
||||
inst_offset = 0 ;
|
||||
for (entry = compiled_program.first;
|
||||
entry != NULL; entry = entry->next) {
|
||||
entry->inst_offset = inst_offset;
|
||||
entry1 = entry->next;
|
||||
if (entry1 && entry1->islabel && is_entry_point(entry1->string)) {
|
||||
while (((inst_offset+1) & 0x3) != 0) {
|
||||
tmp_entry = calloc(sizeof(*tmp_entry), 1);
|
||||
entry->next = tmp_entry;
|
||||
tmp_entry->next = entry1;
|
||||
entry = tmp_entry;
|
||||
tmp_entry->inst_offset = ++inst_offset;
|
||||
}
|
||||
}
|
||||
if (!entry->islabel)
|
||||
inst_offset++;
|
||||
inst_offset++;
|
||||
}
|
||||
|
||||
if (need_export) {
|
||||
if (export_filename) {
|
||||
export_file = fopen(export_filename, "w");
|
||||
} else {
|
||||
export_file = fopen("export.inc", "w");
|
||||
}
|
||||
for (entry = compiled_program.first;
|
||||
entry != NULL; entry = entry->next) {
|
||||
if (entry->islabel)
|
||||
fprintf(export_file, "#define %s_IP %d\n",
|
||||
entry->string, (gen_level == 5 ? 2 : 1)*(entry->inst_offset));
|
||||
}
|
||||
fclose(export_file);
|
||||
}
|
||||
|
||||
for (entry = compiled_program.first;
|
||||
entry != NULL; entry = entry->next) {
|
||||
if (!entry->islabel) {
|
||||
if (entry->instruction.reloc_target) {
|
||||
for (entry1 = entry;
|
||||
entry1 != NULL; entry1 = entry1->next) {
|
||||
entry1 = entry;
|
||||
do {
|
||||
if (entry1->islabel &&
|
||||
strcmp(entry1->string,
|
||||
entry->instruction.reloc_target) == 0) {
|
||||
int offset =
|
||||
entry1->inst_offset - entry->inst_offset;
|
||||
|
||||
int delta = (entry->instruction.header.opcode == BRW_OPCODE_JMPI ? 1 : 0);
|
||||
if (gen_level >= 5)
|
||||
entry->instruction.bits3.ud = 2 * (offset - 1);
|
||||
entry->instruction.bits3.ud = 2 * (offset - delta);
|
||||
else
|
||||
entry->instruction.bits3.ud = offset - 1;
|
||||
entry->instruction.bits3.ud = offset - delta;
|
||||
|
||||
if (entry->instruction.header.opcode == BRW_OPCODE_ELSE)
|
||||
entry->instruction.bits3.if_else.pop_count = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
entry1 = entry1->next;
|
||||
if (entry1 == NULL)
|
||||
entry1 = compiled_program.first;
|
||||
} while (entry1 != entry);
|
||||
if (entry1 == NULL)
|
||||
fprintf(stderr, "can not find lable %s\n",
|
||||
entry->instruction.reloc_target);
|
||||
@ -148,15 +319,20 @@ int main(int argc, char **argv)
|
||||
|
||||
for (entry = compiled_program.first;
|
||||
entry != NULL;
|
||||
entry = entry->next) {
|
||||
entry = entry1) {
|
||||
entry1 = entry->next;
|
||||
if (!entry->islabel)
|
||||
fprintf(output, " { 0x%08x, 0x%08x, 0x%08x, 0x%08x },\n",
|
||||
((int *)(&entry->instruction))[0],
|
||||
((int *)(&entry->instruction))[1],
|
||||
((int *)(&entry->instruction))[2],
|
||||
((int *)(&entry->instruction))[3]);
|
||||
else
|
||||
free(entry->string);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
free_register_table();
|
||||
fflush (output);
|
||||
if (ferror (output)) {
|
||||
perror ("Could not flush output file");
|
||||
|
Loading…
x
Reference in New Issue
Block a user