Add conditional support to assembler. Add align16 dest support to disasm.

This is working towards round-tripping mesa programs. Still need indirect
register addressing and align16 source support.
This commit is contained in:
Keith Packard 2008-04-23 23:10:40 -07:00 committed by Damien Lespiau
parent d8057c9bcd
commit 2033aea3dd
5 changed files with 248 additions and 112 deletions

View File

@ -522,8 +522,9 @@
#define BRW_CONDITIONAL_L 5
#define BRW_CONDITIONAL_LE 6
#define BRW_CONDITIONAL_C 7
#define BRW_CONDITIONAL_O 8
#define BRW_CONDITIONAL_U 9
#define BRW_CONDITIONAL_R 7 /* round increment */
#define BRW_CONDITIONAL_O 8 /* overflow */
#define BRW_CONDITIONAL_U 9 /* unordered */
#define BRW_DEBUG_NONE 0
#define BRW_DEBUG_BREAKPOINT 1

View File

@ -1193,7 +1193,7 @@ struct brw_instruction
GLuint src1_reg_nr:8;
GLuint src1_abs:1;
GLuint src1_negate:1;
GLuint pad:1;
GLuint src1_address_mode:1;
GLuint src1_horiz_stride:2;
GLuint src1_width:3;
GLuint src1_vert_stride:4;
@ -1208,7 +1208,7 @@ struct brw_instruction
GLuint src1_reg_nr:8;
GLuint src1_abs:1;
GLuint src1_negate:1;
GLuint pad0:1;
GLuint src1_address_mode:1;
GLuint src1_swz_z:2;
GLuint src1_swz_w:2;
GLuint pad1:1;
@ -1222,7 +1222,7 @@ struct brw_instruction
GLuint src1_subreg_nr:3;
GLuint src1_abs:1;
GLuint src1_negate:1;
GLuint pad0:1;
GLuint src1_address_mode:1;
GLuint src1_horiz_stride:2;
GLuint src1_width:3;
GLuint src1_vert_stride:4;
@ -1238,7 +1238,7 @@ struct brw_instruction
GLuint src1_subreg_nr:3;
GLuint src1_abs:1;
GLuint src1_negate:1;
GLuint pad0:1;
GLuint src1_address_mode:1;
GLuint src1_swz_z:2;
GLuint src1_swz_w:2;
GLuint pad1:1;

View File

@ -88,17 +88,15 @@ struct {
char *conditional_modifier[16] = {
[BRW_CONDITIONAL_NONE] = "",
[BRW_CONDITIONAL_Z] = ".Z",
[BRW_CONDITIONAL_NZ] = ".NZ",
[BRW_CONDITIONAL_EQ] = ".EQ",
[BRW_CONDITIONAL_NEQ] = ".NEQ",
[BRW_CONDITIONAL_G] = ".G",
[BRW_CONDITIONAL_GE] = ".GE",
[BRW_CONDITIONAL_L] = ".L",
[BRW_CONDITIONAL_LE] = ".LE",
[BRW_CONDITIONAL_C] = ".C",
[BRW_CONDITIONAL_O] = ".O",
[BRW_CONDITIONAL_U] = ".U",
[BRW_CONDITIONAL_Z] = ".e",
[BRW_CONDITIONAL_NZ] = ".ne",
[BRW_CONDITIONAL_G] = ".g",
[BRW_CONDITIONAL_GE] = ".ge",
[BRW_CONDITIONAL_L] = ".l",
[BRW_CONDITIONAL_LE] = ".le",
[BRW_CONDITIONAL_R] = ".r",
[BRW_CONDITIONAL_O] = ".o",
[BRW_CONDITIONAL_U] = ".u",
};
char *negate[2] = {
@ -172,19 +170,17 @@ char *pred_inv[2] = {
};
char *pred_ctrl_align16[16] = {
[0] = "",
[1] = "sequential",
[2] = "replication swizzle .x",
[3] = "replication swizzle .y",
[4] = "replication swizzle .z",
[5] = "replication swizzle .w",
[1] = "",
[2] = ".x",
[3] = ".y",
[4] = ".z",
[5] = ".w",
[6] = ".any4h",
[7] = ".all4h",
};
char *pred_ctrl_align1[16] = {
[0] = "",
[1] = "sequential",
[1] = "",
[2] = ".anyv",
[3] = ".allv",
[4] = ".any2h",
@ -252,6 +248,25 @@ char *reg_file[4] = {
[3] = "imm",
};
char *writemask[16] = {
[0x0] = ".",
[0x1] = ".x",
[0x2] = ".y",
[0x3] = ".xy",
[0x4] = ".z",
[0x5] = ".xz",
[0x6] = ".yz",
[0x7] = ".xyz",
[0x8] = ".w",
[0x9] = ".xw",
[0xa] = ".yw",
[0xb] = ".xyw",
[0xc] = ".zw",
[0xd] = ".xzw",
[0xe] = ".yzw",
[0xf] = "",
};
char *end_of_thread[2] = {
[0] = "",
[1] = "EOT"
@ -361,8 +376,9 @@ static int newline (FILE *f)
static int pad (FILE *f, int c)
{
while (column < c)
do
string (f, " ");
while (column < c);
return 0;
}
@ -394,56 +410,95 @@ static int print_opcode (FILE *file, int id)
return 0;
}
static int reg (FILE *file, GLuint _reg_file, GLuint _reg_nr)
{
int err = 0;
if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
switch (_reg_nr & 0xf0) {
case BRW_ARF_NULL:
string (file, "null");
return -1;
case BRW_ARF_ADDRESS:
format (file, "a%d", _reg_nr & 0x0f);
break;
case BRW_ARF_ACCUMULATOR:
format (file, "acc%d", _reg_nr & 0x0f);
break;
case BRW_ARF_MASK:
format (file, "mask%d", _reg_nr & 0x0f);
break;
case BRW_ARF_MASK_STACK:
format (file, "msd%d", _reg_nr & 0x0f);
break;
case BRW_ARF_STATE:
format (file, "sr%d", _reg_nr & 0x0f);
break;
case BRW_ARF_CONTROL:
format (file, "cr%d", _reg_nr & 0x0f);
break;
case BRW_ARF_NOTIFICATION_COUNT:
format (file, "n%d", _reg_nr & 0x0f);
break;
case BRW_ARF_IP:
string (file, "ip");
return -1;
break;
default:
format (file, "ARF%d", _reg_nr);
break;
}
} else {
err |= control (file, "src reg file", reg_file, _reg_file, NULL);
format (file, "%d", _reg_nr);
}
return err;
}
static int dest (FILE *file, struct brw_instruction *inst)
{
int err = 0;
if (inst->bits1.da1.dest_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
switch (inst->bits1.da1.dest_reg_nr & 0xf0) {
case BRW_ARF_NULL:
string (file, "null");
if (inst->header.access_mode == BRW_ALIGN_1)
{
if (inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT)
{
err |= reg (file, inst->bits1.da1.dest_reg_file, inst->bits1.da1.dest_reg_nr);
if (err == -1)
return 0;
case BRW_ARF_ADDRESS:
format (file, "a%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_ACCUMULATOR:
format (file, "acc%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_MASK:
format (file, "mask%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_MASK_STACK:
format (file, "msd%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_STATE:
format (file, "sr%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_CONTROL:
format (file, "cr%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_NOTIFICATION_COUNT:
format (file, "n%d", inst->bits1.da1.dest_reg_nr & 0x0f);
break;
case BRW_ARF_IP:
string (file, "ip");
break;
default:
format (file, "ARF%d", inst->bits1.da1.dest_reg_nr);
break;
}
} else {
err |= control (file, "dest reg file", reg_file, inst->bits1.da1.dest_reg_file, NULL);
format (file, "%d", inst->bits1.da1.dest_reg_nr);
}
if (inst->bits1.da1.dest_subreg_nr)
format (file, ".%d", inst->bits1.da1.dest_subreg_nr);
format (file, "<%d>", inst->bits1.da1.dest_horiz_stride);
err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL);
}
else
{
err = 1;
string (file, "Indirect align1 address mode not supported");
}
}
else
{
if (inst->bits1.da16.dest_address_mode == BRW_ADDRESS_DIRECT)
{
err |= reg (file, inst->bits1.da16.dest_reg_file, inst->bits1.da16.dest_reg_nr);
if (err == -1)
return 0;
if (inst->bits1.da16.dest_subreg_nr)
format (file, ".%d", inst->bits1.da16.dest_subreg_nr);
err |= control (file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL);
string (file, "<1>");
}
else
{
err = 1;
string (file, "Indirect align16 address mode not supported");
}
}
return 0;
}
static int src (FILE *file, GLuint type, GLuint _reg_file,
static int src_da1 (FILE *file, GLuint type, GLuint _reg_file,
GLuint _vert_stride, GLuint _width, GLuint _horiz_stride,
GLuint reg_num, GLuint sub_reg_num, GLuint __abs, GLuint _negate)
{
@ -451,8 +506,9 @@ static int src (FILE *file, GLuint type, GLuint _reg_file,
err |= control (file, "negate", negate, _negate, NULL);
err |= control (file, "abs", _abs, __abs, NULL);
err |= control (file, "src reg file", reg_file, _reg_file, NULL);
format (file, "%d", reg_num);
err |= reg (file, _reg_file, reg_num);
if (err == -1)
return 0;
if (sub_reg_num)
format (file, ".%d", sub_reg_num);
string (file, "<");
@ -500,8 +556,11 @@ static int src0 (FILE *file, struct brw_instruction *inst)
if (inst->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE)
return imm (file, inst->bits1.da1.src0_reg_type,
inst);
else
return src (file,
else if (inst->header.access_mode == BRW_ALIGN_1)
{
if (inst->bits2.da1.src0_address_mode == BRW_ADDRESS_DIRECT)
{
return src_da1 (file,
inst->bits1.da1.src0_reg_type,
inst->bits1.da1.src0_reg_file,
inst->bits2.da1.src0_vert_stride,
@ -512,14 +571,37 @@ static int src0 (FILE *file, struct brw_instruction *inst)
inst->bits2.da1.src0_abs,
inst->bits2.da1.src0_negate);
}
else
{
string (file, "Indirect align1 address mode not supported");
return 1;
}
}
else
{
if (inst->bits2.da16.src0_address_mode == BRW_ADDRESS_DIRECT)
{
string (file, "Indirect align16 address mode not supported");
return 1;
}
else
{
string (file, "Indirect align16 address mode not supported");
return 1;
}
}
}
static int src1 (FILE *file, struct brw_instruction *inst)
{
if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)
return imm (file, inst->bits1.da1.src1_reg_type,
inst);
else
return src (file,
else if (inst->header.access_mode == BRW_ALIGN_1)
{
if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT)
{
return src_da1 (file,
inst->bits1.da1.src1_reg_type,
inst->bits1.da1.src1_reg_file,
inst->bits3.da1.src1_vert_stride,
@ -530,28 +612,55 @@ static int src1 (FILE *file, struct brw_instruction *inst)
inst->bits3.da1.src1_abs,
inst->bits3.da1.src1_negate);
}
else
{
string (file, "Indirect align1 address mode not supported");
return 1;
}
}
else
{
if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT)
{
string (file, "Indirect align16 address mode not supported");
return 1;
}
else
{
string (file, "Indirect align16 address mode not supported");
return 1;
}
}
}
int disasm (FILE *file, struct brw_instruction *inst)
{
int err = 0;
int space = 0;
if (inst->header.predicate_control || inst->header.predicate_inverse) {
if (inst->header.predicate_control) {
string (file, "(");
space = 0;
err |= control (file, "predicate inverse", pred_inv, inst->header.predicate_inverse, &space);
err |= control (file, "predicate inverse", pred_inv, inst->header.predicate_inverse, NULL);
string (file, "f0");
if (inst->bits2.da1.flag_reg_nr)
format (file, ".%d", inst->bits2.da1.flag_reg_nr);
if (inst->header.access_mode == BRW_ALIGN_1)
err |= control (file, "predicate control align1", pred_ctrl_align1,
inst->header.predicate_control, &space);
inst->header.predicate_control, NULL);
else
err |= control (file, "predicate control align16", pred_ctrl_align16,
inst->header.predicate_control, &space);
inst->header.predicate_control, NULL);
string (file, ") ");
}
err |= print_opcode (file, inst->header.opcode);
err |= control (file, "saturate", saturate, inst->header.saturate, NULL);
err |= control (file, "debug control", debug_ctrl, inst->header.debug_control, NULL);
if (inst->header.opcode != BRW_OPCODE_SEND)
err |= control (file, "conditional modifier", conditional_modifier,
inst->header.destreg__conditionalmod, NULL);
if (inst->header.opcode != BRW_OPCODE_NOP) {
string (file, "(");
err |= control (file, "execution size", exec_size, inst->header.execution_size, NULL);
@ -560,9 +669,6 @@ int disasm (FILE *file, struct brw_instruction *inst)
if (inst->header.opcode == BRW_OPCODE_SEND)
format (file, " %d", inst->header.destreg__conditionalmod);
else
err |= control (file, "conditional modifier", conditional_modifier,
inst->header.destreg__conditionalmod, NULL);
if (opcode[inst->header.opcode].ndst > 0) {
pad (file, 16);

View File

@ -86,7 +86,9 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
%token ALIGN1 ALIGN16 SECHALF COMPR SWITCH ATOMIC NODDCHK NODDCLR
%token MASK_DISABLE BREAKPOINT EOT
%token ANY2H ALL2H ANY4H ALL4H ANY8H ALL8H ANY16H ALL16H
%token SEQ ANY2H ALL2H ANY4H ALL4H ANY8H ALL8H ANY16H ALL16H ANYV ALLV
%token <integer> ZERO EQUAL NOT_ZERO NOT_EQUAL GREATER GREATER_EQUAL LESS LESS_EQUAL
%token <integer> ROUND_INCREMENT OVERFLOW UNORDERED
%token <integer> GENREG MSGREG ADDRESSREG ACCREG FLAGREG
%token <integer> MASKREG AMASK IMASK LMASK CMASK
%token <integer> MASKSTACKREG LMS IMS MASKSTACKDEPTHREG IMSD LMSD
@ -1331,11 +1333,13 @@ predstate: /* empty */ { $$ = 0; }
| MINUS { $$ = 1; }
;
predctrl: /* empty */ { $$ = BRW_PREDICATE_NONE; }
predctrl: /* empty */ { $$ = BRW_PREDICATE_NORMAL; }
| DOT X { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_X; }
| DOT Y { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Y; }
| DOT Z { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Z; }
| DOT W { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_W; }
| ANYV { $$ = BRW_PREDICATE_ALIGN1_ANYV; }
| ALLV { $$ = BRW_PREDICATE_ALIGN1_ALLV; }
| ANY2H { $$ = BRW_PREDICATE_ALIGN1_ANY2H; }
| ALL2H { $$ = BRW_PREDICATE_ALIGN1_ALL2H; }
| ANY4H { $$ = BRW_PREDICATE_ALIGN1_ANY4H; }
@ -1372,7 +1376,18 @@ saturate: /* empty */ { $$ = BRW_INSTRUCTION_NORMAL; }
| DOT SATURATE { $$ = BRW_INSTRUCTION_SATURATE; }
;
conditionalmodifier: { $$ = 0; }
conditionalmodifier: /* empty */ { $$ = BRW_CONDITIONAL_NONE; }
| ZERO
| EQUAL
| NOT_ZERO
| NOT_EQUAL
| GREATER
| GREATER_EQUAL
| LESS
| LESS_EQUAL
| ROUND_INCREMENT
| OVERFLOW
| UNORDERED
;
/* 1.4.13: Instruction options */
@ -1632,7 +1647,7 @@ void set_direct_src_operand(struct src_operand *src, struct direct_reg *reg,
src->reg_nr = reg->reg_nr;
src->vert_stride = 0;
src->width = 0;
src->horiz_stride = 1;
src->horiz_stride = 0;
src->negate = 0;
src->abs = 0;
src->swizzle_set = 0;

View File

@ -284,14 +284,28 @@ extern char *input_filename;
"scalar" { return SCALAR; }
/* predicate control */
"any2h" { return ANY2H; }
"all2h" { return ALL2H; }
"any4h" { return ANY4H; }
"all4h" { return ALL4H; }
"any8h" { return ANY8H; }
"all8h" { return ALL8H; }
"any16h" { return ANY16H; }
"all16h" { return ALL16H; }
".anyv" { return ANYV; }
".allv" { return ALLV; }
".any2h" { return ANY2H; }
".all2h" { return ALL2H; }
".any4h" { return ANY4H; }
".all4h" { return ALL4H; }
".any8h" { return ANY8H; }
".all8h" { return ALL8H; }
".any16h" { return ANY16H; }
".all16h" { return ALL16H; }
".z" { yylval.integer = BRW_CONDITIONAL_Z; return ZERO; }
".e" { yylval.integer = BRW_CONDITIONAL_Z; return EQUAL; }
".nz" { yylval.integer = BRW_CONDITIONAL_NZ; return NOT_ZERO; }
".ne" { yylval.integer = BRW_CONDITIONAL_NZ; return NOT_EQUAL; }
".g" { yylval.integer = BRW_CONDITIONAL_G; return GREATER; }
".ge" { yylval.integer = BRW_CONDITIONAL_GE; return GREATER_EQUAL; }
".l" { yylval.integer = BRW_CONDITIONAL_L; return LESS; }
".le" { yylval.integer = BRW_CONDITIONAL_LE; return LESS_EQUAL; }
".r" { yylval.integer = BRW_CONDITIONAL_R; return ROUND_INCREMENT; }
".o" { yylval.integer = BRW_CONDITIONAL_O; return OVERFLOW; }
".u" { yylval.integer = BRW_CONDITIONAL_U; return UNORDERED; }
/* channel selectors */
"x" {