summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomer Hsing <homer.xing@intel.com>2012-09-21 12:33:13 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-09-28 04:06:00 -0400
commite5962affedd34044ec261bcfc31fb7f41c8033d0 (patch)
tree15b17d6b5c6a190aadbd665bf2e59206aaa5f9f4
parent24280aedbf353b2e68faa063fca0b32f72fc6f54 (diff)
Support subroutine instructions, CALL & RET
-rw-r--r--src/brw_defines.h2
-rw-r--r--src/gen4asm.h2
-rw-r--r--src/gram.y51
-rw-r--r--src/lex.l2
4 files changed, 56 insertions, 1 deletions
diff --git a/src/brw_defines.h b/src/brw_defines.h
index 765d7c7..6cc161f 100644
--- a/src/brw_defines.h
+++ b/src/brw_defines.h
@@ -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
diff --git a/src/gen4asm.h b/src/gen4asm.h
index 3a8d595..8178290 100644
--- a/src/gen4asm.h
+++ b/src/gen4asm.h
@@ -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;
diff --git a/src/gram.y b/src/gram.y
index c7d4e62..72a2a80 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -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:
diff --git a/src/lex.l b/src/lex.l
index f789212..e4492f0 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -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; }