Support subroutine instructions, CALL & RET

This commit is contained in:
Homer Hsing 2012-09-21 12:33:13 +08:00 committed by Damien Lespiau
parent c0ebde2786
commit a7b1c09d18
4 changed files with 56 additions and 1 deletions

View File

@ -585,7 +585,9 @@
#define BRW_OPCODE_CONTINUE 41
#define BRW_OPCODE_HALT 42
#define BRW_OPCODE_MSAVE 44
#define BRW_OPCODE_CALL 44
#define BRW_OPCODE_MRESTORE 45
#define BRW_OPCODE_RET 45
#define BRW_OPCODE_PUSH 46
#define BRW_OPCODE_POP 47
#define BRW_OPCODE_WAIT 48

View File

@ -107,7 +107,7 @@ struct src_operand {
int swizzle_set;
int swizzle_x, swizzle_y, swizzle_z, swizzle_w;
uint32_t imm32; /* only set if reg_file == BRW_IMMEDIATE_VALUE */
uint32_t imm32; /* set if reg_file == BRW_IMMEDIATE_VALUE or it is expressing a branch offset */
char *reloc_target; /* bspec: branching instructions JIP and UIP are source operands */
} src_operand;

View File

@ -120,6 +120,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
%token <integer> PUSH MREST POP WAIT DO ENDIF ILLEGAL
%token <integer> MATH_INST
%token <integer> MAD LRP BFE BFI2 SUBB
%token <integer> CALL RET
%token NULL_TOKEN MATH SAMPLER GATEWAY READ WRITE URB THREAD_SPAWNER VME DATA_PORT
@ -160,6 +161,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
%type <instruction> msgtarget
%type <instruction> instoptions instoption_list predicate
%type <instruction> mathinstruction
%type <instruction> subroutineinstruction
%type <string> label
%type <program> instrseq
%type <integer> instoption
@ -382,6 +384,55 @@ instruction: unaryinstruction
| syncinstruction
| specialinstruction
| mathinstruction
| subroutineinstruction
;
subroutineinstruction:
predicate CALL execsize dst relativelocation instoptions
{
if($3 != 1 /* encoded int 2 */) {
fprintf(stderr, "The execution size of CALL should be 2.\n");
YYERROR;
}
if($4.reg_type != BRW_REGISTER_TYPE_UD && $4.reg_type != BRW_REGISTER_TYPE_D) {
fprintf(stderr, "The dest type of CALL should be UD or D.\n");
YYERROR;
}
memset(&$$, 0, sizeof($$));
set_instruction_predicate(&$$, &$1);
$$.header.opcode = $2;
$$.header.execution_size = $3;
set_instruction_dest(&$$, &$4);
$$.first_reloc_target = $5.reloc_target;
$$.first_reloc_offset = $5.imm32;
}
| predicate RET execsize dstoperandex src instoptions
{
if($3 != 1 /* encoded int 2 */) {
fprintf(stderr, "The execution size of RET should be 2.\n");
YYERROR;
}
if($4.reg_file != BRW_ARCHITECTURE_REGISTER_FILE && $4.reg_nr != BRW_ARF_NULL) {
fprintf(stderr, "The dest reg of RET should be NULL.\n");
YYERROR;
}
if($5.reg_type != BRW_REGISTER_TYPE_UD && $5.reg_type != BRW_REGISTER_TYPE_D) {
fprintf(stderr, "The source reg type of RET should be UD or D.\n");
YYERROR;
}
if($5.horiz_stride != 1 /*encoded 1*/
|| $5.width != 1 /*encoded 2*/
|| $5.vert_stride != 2 /*encoded 2*/) {
fprintf(stderr, "The source reg region of RET should be <2,2,1>.\n");
YYERROR;
}
memset(&$$, 0, sizeof($$));
set_instruction_predicate(&$$, &$1);
$$.header.opcode = $2;
$$.header.execution_size = $3;
set_instruction_dest(&$$, &$4);
set_instruction_src0(&$$, &$5);
}
;
unaryinstruction:

View File

@ -136,6 +136,8 @@ yylval.integer = BRW_CHANNEL_W;
"wait" { yylval.integer = BRW_OPCODE_WAIT; return WAIT; }
"do" { yylval.integer = BRW_OPCODE_DO; return DO; }
"endif" { yylval.integer = BRW_OPCODE_ENDIF; return ENDIF; }
"call" { yylval.integer = BRW_OPCODE_CALL; return CALL; }
"ret" { yylval.integer = BRW_OPCODE_RET; return RET; }
"pln" { yylval.integer = BRW_OPCODE_PLN; return PLN; }