summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-08-31 10:21:15 -0700
committerDamien Lespiau <damien.lespiau@intel.com>2013-03-04 15:54:23 +0000
commit1e907c7aed7c11f9b29ca8ee4d6e7916d81a5277 (patch)
treef446cbea43c82e1975e70a352e9e876a35d89bd5
parentd77712994d7a6dd183e0274c2afb5f246b06c0d1 (diff)
Add rules for branch and jump instructions.
Untested.
-rw-r--r--assembler/TODO1
-rw-r--r--assembler/src/gram.y110
2 files changed, 108 insertions, 3 deletions
diff --git a/assembler/TODO b/assembler/TODO
index f2ad9ced..4e2a4dab 100644
--- a/assembler/TODO
+++ b/assembler/TODO
@@ -7,3 +7,4 @@
- more error cases.
- boolean types
- replace GL* with non-GL?
+- labels for branch/jump instruction destinations
diff --git a/assembler/src/gram.y b/assembler/src/gram.y
index 31b2a3ac..3fcfa52a 100644
--- a/assembler/src/gram.y
+++ b/assembler/src/gram.y
@@ -43,6 +43,8 @@ void set_instruction_predicate(struct brw_instruction *instr,
struct brw_instruction *predicate);
void set_instruction_predicate(struct brw_instruction *instr,
struct brw_instruction *predicate);
+void set_direct_dst_operand(struct dst_operand *dst, struct direct_reg *reg,
+ int type);
void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
int type);
@@ -113,12 +115,12 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
%type <instruction> instruction unaryinstruction binaryinstruction
%type <instruction> binaryaccinstruction triinstruction sendinstruction
-%type <instruction> specialinstruction
+%type <instruction> jumpinstruction branchloopinstruction specialinstruction
%type <instruction> msgtarget
%type <instruction> instoptions instoption_list predicate
%type <program> instrseq
%type <integer> instoption
-%type <integer> unaryop binaryop binaryaccop
+%type <integer> unaryop binaryop binaryaccop branchloopop
%type <integer> conditionalmodifier saturate negate abs chansel
%type <integer> writemask_x writemask_y writemask_z writemask_w
%type <integer> regtype srcimmtype execsize dstregion immaddroffset
@@ -138,6 +140,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
%type <src_operand> directsrcoperand srcarchoperandex directsrcaccoperand
%type <src_operand> indirectsrcoperand
%type <src_operand> src srcimm imm32reg payload srcacc srcaccimm swizzle
+%type <src_operand> relativelocation relativelocation2
%%
ROOT: instrseq
@@ -178,6 +181,8 @@ instruction: unaryinstruction
| binaryinstruction
| binaryaccinstruction
| triinstruction
+ | jumpinstruction
+ | branchloopinstruction
| specialinstruction
;
@@ -282,6 +287,55 @@ sendinstruction: predicate SEND execsize INTEGER post_dst payload msgtarget
}
;
+/* XXX: This should probably allow predication (i.e. be a branchloopop),
+ * though the BNF didn't specify it.
+ */
+jumpinstruction: JMPI relativelocation2
+ {
+ struct direct_reg dst;
+ struct dst_operand ip_dst;
+ struct src_operand ip_src;
+
+ /* 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.
+ */
+
+ bzero(&$$, sizeof($$));
+ $$.header.opcode = $1;
+ set_direct_dst_operand(&ip_dst, &dst, BRW_REGISTER_TYPE_UD);
+ set_instruction_dest(&$$, &ip_dst);
+ set_direct_src_operand(&ip_src, &dst, BRW_REGISTER_TYPE_UD);
+ set_instruction_src0(&$$, &ip_src);
+ set_instruction_src1(&$$, &$2);
+ }
+;
+
+branchloopinstruction:
+ predicate branchloopop relativelocation
+ {
+ struct direct_reg dst;
+ struct dst_operand ip_dst;
+ struct src_operand ip_src;
+
+ /* The branch instructions require that the IP register
+ * be the destination and first source operand, while the
+ * offset is the second source operand. The offset is added
+ * to the pre-incremented IP.
+ */
+
+ bzero(&$$, sizeof($$));
+ $$.header.opcode = $2;
+ set_instruction_predicate(&$$, &$1);
+ set_direct_dst_operand(&ip_dst, &dst, BRW_REGISTER_TYPE_UD);
+ set_instruction_dest(&$$, &ip_dst);
+ set_direct_src_operand(&ip_src, &dst, BRW_REGISTER_TYPE_UD);
+ set_instruction_src0(&$$, &ip_src);
+ set_instruction_src1(&$$, &$3);
+ }
+;
+
branchloopop: IF | IFF | WHILE
;
@@ -309,7 +363,6 @@ specialinstruction: NOP
$$.bits1.da1.src1_reg_type = BRW_REGISTER_TYPE_UD;
$$.bits3.if_else.pop_count = 1;
}
-
;
/* XXX! */
@@ -916,6 +969,37 @@ nullreg: NULL_TOKEN
}
;
+/* 1.4.6: Relative locations */
+relativelocation: imm32
+ {
+ if ($1 > 32767 || $1 < -32768) {
+ fprintf(stderr,
+ "error: relative offset %d out of range\n");
+ YYERROR;
+ }
+
+ $$.reg_file = BRW_IMMEDIATE_VALUE;
+ $$.reg_type = BRW_REGISTER_TYPE_D;
+ $$.imm32 = $1;
+ }
+;
+
+relativelocation2:
+ imm32
+ {
+ $$.reg_file = BRW_IMMEDIATE_VALUE;
+ $$.reg_type = BRW_REGISTER_TYPE_D;
+ $$.imm32 = $1;
+ }
+ | directgenreg region regtype
+ {
+ set_direct_src_operand(&$$, &$1, $3);
+ $$.vert_stride = $2.vert_stride;
+ $$.width = $2.width;
+ $$.horiz_stride = $2.horiz_stride;
+ }
+;
+
/* 1.4.7: Regions */
dstregion: LANGLE INTEGER RANGLE
{
@@ -1336,10 +1420,25 @@ void set_instruction_predicate(struct brw_instruction *instr,
instr->bits2.da1.flag_reg_nr = predicate->bits2.da1.flag_reg_nr;
}
+void set_direct_dst_operand(struct dst_operand *dst, struct direct_reg *reg,
+ int type)
+{
+ bzero(dst, sizeof(*dst));
+ dst->address_mode = BRW_ADDRESS_DIRECT;
+ dst->reg_file = reg->reg_file;
+ dst->reg_nr = reg->reg_nr;
+ dst->subreg_nr = reg->subreg_nr;
+ dst->reg_type = type;
+ dst->horiz_stride = 1;
+ dst->writemask_set = 0;
+ dst->writemask = 0xf;
+}
+
void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
int type)
{
bzero(src, sizeof(*src));
+ src->address_mode = BRW_ADDRESS_DIRECT;
src->reg_file = reg->reg_file;
src->reg_type = type;
src->subreg_nr = reg->subreg_nr;
@@ -1349,4 +1448,9 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
src->horiz_stride = 1;
src->negate = 0;
src->abs = 0;
+ src->swizzle_set = 0;
+ src->swizzle_x = BRW_CHANNEL_X;
+ src->swizzle_y = BRW_CHANNEL_Y;
+ src->swizzle_z = BRW_CHANNEL_Z;
+ src->swizzle_w = BRW_CHANNEL_W;
}