mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-07-25 10:55:58 +00:00
Add support for labeled and conditional branches
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
5a2ec836e1
commit
be9bcee15f
@ -1336,6 +1336,7 @@ struct brw_instruction
|
|||||||
GLint id;
|
GLint id;
|
||||||
GLfloat fd;
|
GLfloat fd;
|
||||||
} bits3;
|
} bits3;
|
||||||
|
char *reloc_target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,11 +106,14 @@ typedef struct {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This structure is just the list container for instructions accumulated by
|
* This structure is just the list container for instructions accumulated by
|
||||||
* the parser.
|
* the parser and labels.
|
||||||
*/
|
*/
|
||||||
struct brw_program_instruction {
|
struct brw_program_instruction {
|
||||||
struct brw_instruction instruction;
|
struct brw_instruction instruction;
|
||||||
struct brw_program_instruction *next;
|
struct brw_program_instruction *next;
|
||||||
|
GLuint islabel;
|
||||||
|
GLuint inst_offset;
|
||||||
|
char *string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
|
|||||||
%start ROOT
|
%start ROOT
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
char *s;
|
char *string;
|
||||||
int integer;
|
int integer;
|
||||||
double number;
|
double number;
|
||||||
struct brw_instruction instruction;
|
struct brw_instruction instruction;
|
||||||
@ -71,6 +71,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
|
|||||||
struct src_operand src_operand;
|
struct src_operand src_operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%token COLON
|
||||||
%token SEMICOLON
|
%token SEMICOLON
|
||||||
%token LPAREN RPAREN
|
%token LPAREN RPAREN
|
||||||
%token LANGLE RANGLE
|
%token LANGLE RANGLE
|
||||||
@ -108,6 +109,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
|
|||||||
%token SATURATE
|
%token SATURATE
|
||||||
|
|
||||||
%token <integer> INTEGER
|
%token <integer> INTEGER
|
||||||
|
%token <string> STRING
|
||||||
%token <number> NUMBER
|
%token <number> NUMBER
|
||||||
|
|
||||||
%token <integer> INV LOG EXP SQRT RSQ POW SIN COS SINCOS INTDIV INTMOD
|
%token <integer> INV LOG EXP SQRT RSQ POW SIN COS SINCOS INTDIV INTMOD
|
||||||
@ -122,6 +124,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
|
|||||||
%type <instruction> breakinstruction syncinstruction specialinstruction
|
%type <instruction> breakinstruction syncinstruction specialinstruction
|
||||||
%type <instruction> msgtarget
|
%type <instruction> msgtarget
|
||||||
%type <instruction> instoptions instoption_list predicate
|
%type <instruction> instoptions instoption_list predicate
|
||||||
|
%type <string> label
|
||||||
%type <program> instrseq
|
%type <program> instrseq
|
||||||
%type <integer> instoption
|
%type <integer> instoption
|
||||||
%type <integer> unaryop binaryop binaryaccop branchloopop breakop
|
%type <integer> unaryop binaryop binaryaccop branchloopop breakop
|
||||||
@ -155,6 +158,13 @@ ROOT: instrseq
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
label: STRING COLON
|
||||||
|
{
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
instrseq: instruction SEMICOLON instrseq
|
instrseq: instruction SEMICOLON instrseq
|
||||||
{
|
{
|
||||||
struct brw_program_instruction *list_entry =
|
struct brw_program_instruction *list_entry =
|
||||||
@ -176,6 +186,16 @@ instrseq: instruction SEMICOLON instrseq
|
|||||||
|
|
||||||
$$.first = list_entry;
|
$$.first = list_entry;
|
||||||
}
|
}
|
||||||
|
| label instrseq
|
||||||
|
{
|
||||||
|
struct brw_program_instruction *list_entry =
|
||||||
|
calloc(sizeof(struct brw_program_instruction), 1);
|
||||||
|
list_entry->string = $1;
|
||||||
|
list_entry->islabel = 1;
|
||||||
|
list_entry->next = $2.first;
|
||||||
|
$2.first = list_entry;
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
| error SEMICOLON instrseq
|
| error SEMICOLON instrseq
|
||||||
{
|
{
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
@ -296,10 +316,7 @@ sendinstruction: predicate SEND execsize INTEGER post_dst payload msgtarget
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/* XXX: This should probably allow predication (i.e. be a branchloopop),
|
jumpinstruction: predicate JMPI relativelocation2
|
||||||
* though the BNF didn't specify it.
|
|
||||||
*/
|
|
||||||
jumpinstruction: JMPI relativelocation2
|
|
||||||
{
|
{
|
||||||
struct direct_reg dst;
|
struct direct_reg dst;
|
||||||
struct dst_operand ip_dst;
|
struct dst_operand ip_dst;
|
||||||
@ -315,12 +332,43 @@ jumpinstruction: JMPI relativelocation2
|
|||||||
dst.subreg_nr = 0;
|
dst.subreg_nr = 0;
|
||||||
|
|
||||||
bzero(&$$, sizeof($$));
|
bzero(&$$, sizeof($$));
|
||||||
$$.header.opcode = $1;
|
$$.header.opcode = $2;
|
||||||
set_direct_dst_operand(&ip_dst, &dst, BRW_REGISTER_TYPE_UD);
|
set_direct_dst_operand(&ip_dst, &dst, BRW_REGISTER_TYPE_UD);
|
||||||
|
set_instruction_predicate(&$$, &$1);
|
||||||
set_instruction_dest(&$$, &ip_dst);
|
set_instruction_dest(&$$, &ip_dst);
|
||||||
set_direct_src_operand(&ip_src, &dst, BRW_REGISTER_TYPE_UD);
|
set_direct_src_operand(&ip_src, &dst, BRW_REGISTER_TYPE_UD);
|
||||||
set_instruction_src0(&$$, &ip_src);
|
set_instruction_src0(&$$, &ip_src);
|
||||||
set_instruction_src1(&$$, &$2);
|
set_instruction_src1(&$$, &$3);
|
||||||
|
}
|
||||||
|
| predicate JMPI STRING
|
||||||
|
{
|
||||||
|
struct direct_reg dst;
|
||||||
|
struct dst_operand ip_dst;
|
||||||
|
struct src_operand ip_src;
|
||||||
|
struct src_operand imm;
|
||||||
|
|
||||||
|
/* The jump instruction requires that the IP register
|
||||||
|
* be the destination and first source operand, while the
|
||||||
|
* offset is the second source operand. The next instruction
|
||||||
|
is the post-incremented IP plus the offset.
|
||||||
|
*/
|
||||||
|
dst.reg_file = BRW_ARCHITECTURE_REGISTER_FILE;
|
||||||
|
dst.reg_nr = BRW_ARF_IP;
|
||||||
|
dst.subreg_nr = 0;
|
||||||
|
memset (&imm, '\0', sizeof (imm));
|
||||||
|
imm.reg_file = BRW_IMMEDIATE_VALUE;
|
||||||
|
imm.reg_type = BRW_REGISTER_TYPE_D;
|
||||||
|
imm.imm32 = 0;
|
||||||
|
|
||||||
|
bzero(&$$, sizeof($$));
|
||||||
|
$$.header.opcode = $2;
|
||||||
|
set_direct_dst_operand(&ip_dst, &dst, BRW_REGISTER_TYPE_UD);
|
||||||
|
set_instruction_dest(&$$, &ip_dst);
|
||||||
|
set_instruction_predicate(&$$, &$1);
|
||||||
|
set_direct_src_operand(&ip_src, &dst, BRW_REGISTER_TYPE_UD);
|
||||||
|
set_instruction_src0(&$$, &ip_src);
|
||||||
|
set_instruction_src1(&$$, &imm);
|
||||||
|
$$.reloc_target = $3;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "gram.h"
|
#include "gram.h"
|
||||||
#include "brw_defines.h"
|
#include "brw_defines.h"
|
||||||
|
|
||||||
|
#include "string.h"
|
||||||
int saved_state = 0;
|
int saved_state = 0;
|
||||||
extern char *input_filename;
|
extern char *input_filename;
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ extern char *input_filename;
|
|||||||
"transpose" { return TRANSPOSE; }
|
"transpose" { return TRANSPOSE; }
|
||||||
"interleave" { return INTERLEAVE; }
|
"interleave" { return INTERLEAVE; }
|
||||||
|
|
||||||
|
":" { return COLON; }
|
||||||
";" { return SEMICOLON; }
|
";" { return SEMICOLON; }
|
||||||
"(" { return LPAREN; }
|
"(" { return LPAREN; }
|
||||||
")" { return RPAREN; }
|
")" { return RPAREN; }
|
||||||
@ -171,7 +173,7 @@ extern char *input_filename;
|
|||||||
* rather than the reg number, to avoid a shift/reduce conflict in the
|
* rather than the reg number, to avoid a shift/reduce conflict in the
|
||||||
* predicate control.
|
* predicate control.
|
||||||
*/
|
*/
|
||||||
"f0.[0-9]+" {
|
"f0."[0-9]+ {
|
||||||
yylval.integer = atoi(yytext + 3);
|
yylval.integer = atoi(yytext + 3);
|
||||||
return FLAGREG;
|
return FLAGREG;
|
||||||
}
|
}
|
||||||
@ -326,6 +328,11 @@ extern char *input_filename;
|
|||||||
return W;
|
return W;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[a-zA-Z_][0-9a-zA-Z_]* {
|
||||||
|
yylval.string = strdup(yytext);
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
0x[0-9a-fA-F][0-9a-fA-F]* {
|
0x[0-9a-fA-F][0-9a-fA-F]* {
|
||||||
yylval.integer = strtoul(yytext + 2, NULL, 16);
|
yylval.integer = strtoul(yytext + 2, NULL, 16);
|
||||||
return INTEGER;
|
return INTEGER;
|
||||||
|
@ -55,8 +55,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
char *output_file = NULL;
|
char *output_file = NULL;
|
||||||
FILE *output = stdout;
|
FILE *output = stdout;
|
||||||
struct brw_program_instruction *entry;
|
struct brw_program_instruction *entry, *entry1;
|
||||||
int err;
|
int err, inst_offset;
|
||||||
char o;
|
char o;
|
||||||
|
|
||||||
while ((o = getopt_long(argc, argv, "o:", longopts, NULL)) != -1) {
|
while ((o = getopt_long(argc, argv, "o:", longopts, NULL)) != -1) {
|
||||||
@ -98,22 +98,54 @@ int main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
inst_offset = 0 ;
|
||||||
for (entry = compiled_program.first;
|
for (entry = compiled_program.first;
|
||||||
entry != NULL;
|
entry != NULL; entry = entry->next) {
|
||||||
entry = entry->next) {
|
entry->inst_offset = inst_offset;
|
||||||
|
if (!entry->islabel)
|
||||||
|
inst_offset++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
if (entry1->islabel &&
|
||||||
|
strcmp(entry1->string,
|
||||||
|
entry->instruction.reloc_target) == 0) {
|
||||||
|
int offset =
|
||||||
|
entry1->inst_offset - entry->inst_offset;
|
||||||
|
entry->instruction.bits3.ud = offset - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (entry1 == NULL)
|
||||||
|
fprintf(stderr, "can not find lable %s\n",
|
||||||
|
entry->instruction.reloc_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (entry = compiled_program.first;
|
||||||
|
entry != NULL;
|
||||||
|
entry = entry->next) {
|
||||||
|
if (!entry->islabel)
|
||||||
fprintf(output, " { 0x%08x, 0x%08x, 0x%08x, 0x%08x },\n",
|
fprintf(output, " { 0x%08x, 0x%08x, 0x%08x, 0x%08x },\n",
|
||||||
((int *)(&entry->instruction))[0],
|
((int *)(&entry->instruction))[0],
|
||||||
((int *)(&entry->instruction))[1],
|
((int *)(&entry->instruction))[1],
|
||||||
((int *)(&entry->instruction))[2],
|
((int *)(&entry->instruction))[2],
|
||||||
((int *)(&entry->instruction))[3]);
|
((int *)(&entry->instruction))[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fflush (output);
|
fflush (output);
|
||||||
if (ferror (output)) {
|
if (ferror (output)) {
|
||||||
perror ("Could not flush output file");
|
perror ("Could not flush output file");
|
||||||
if (output_file)
|
if (output_file)
|
||||||
unlink (output_file);
|
unlink (output_file);
|
||||||
err = 1;
|
err = 1;
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user