summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2015-04-01 11:18:40 -0400
committerRob Clark <robdclark@gmail.com>2015-04-01 11:33:28 -0400
commited394f8454ead6e8bdc5dcf8b1e34f5f1a05cc21 (patch)
treeaba6334bf61a3d0b77fa4bae70b3d4b16f6c9995
parent99eccf0a52c794914840cf10a43eec7f6b54f36a (diff)
ir3test: add support for @const immediates
This lets the compiler tell us where the immediates are and what values they should have, so that we can test two different compiler outputs from same tgsi src, even if there are changes in where/if immediates are placed in const registers.
-rw-r--r--asm/ir-a3xx.c14
-rw-r--r--asm/ir-a3xx.h10
-rw-r--r--asm/lexer.l5
-rw-r--r--asm/parser.y17
-rw-r--r--ir3test.c18
-rw-r--r--util.h10
6 files changed, 69 insertions, 5 deletions
diff --git a/asm/ir-a3xx.c b/asm/ir-a3xx.c
index 0768a15..9f64b0a 100644
--- a/asm/ir-a3xx.c
+++ b/asm/ir-a3xx.c
@@ -600,6 +600,20 @@ struct ir3_in * ir3_in_create(struct ir3_shader *shader, int rstart,
return o;
}
+struct ir3_const * ir3_const_create(struct ir3_shader *shader,
+ int cstart, uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3)
+{
+ struct ir3_const *c = ir3_alloc(shader, sizeof(struct ir3_const));
+ c->val[0] = v0;
+ c->val[1] = v1;
+ c->val[2] = v2;
+ c->val[3] = v3;
+ c->cstart = reg_create_from_num(shader, cstart, IR3_REG_CONST);
+ assert(shader->consts_count < ARRAY_SIZE(shader->consts));
+ shader->consts[shader->consts_count++] = c;
+ return c;
+}
+
struct ir3_instruction * ir3_instr_create(struct ir3_shader *shader,
int category, opc_t opc)
{
diff --git a/asm/ir-a3xx.h b/asm/ir-a3xx.h
index c630888..58988cb 100644
--- a/asm/ir-a3xx.h
+++ b/asm/ir-a3xx.h
@@ -127,6 +127,7 @@ struct ir3_instruction {
/* somewhat arbitrary limits.. */
#define MAX_OUTS 32
#define MAX_INS 32
+#define MAX_CONSTS 32
struct ir3_out {
const char *name;
@@ -138,6 +139,11 @@ struct ir3_in {
struct ir3_register *rstart; /* first register */
};
+struct ir3_const {
+ uint32_t val[4];
+ struct ir3_register *cstart; /* first const register */
+};
+
/* this is just large to cope w/ the large test *.asm: */
#define MAX_INSTRS 10240
@@ -152,6 +158,8 @@ struct ir3_shader {
struct ir3_out *outs[MAX_OUTS];
uint32_t ins_count;
struct ir3_in *ins[MAX_INS];
+ uint32_t consts_count;
+ struct ir3_const *consts[MAX_CONSTS];
};
struct ir3_shader * ir3_shader_create(void);
@@ -162,6 +170,8 @@ int ir3_shader_assemble(struct ir3_shader *shader,
struct ir3_out * ir3_out_create(struct ir3_shader *shader, int rstart, const char *name);
struct ir3_in * ir3_in_create(struct ir3_shader *shader, int rstart, const char *name);
+struct ir3_const * ir3_const_create(struct ir3_shader *shader,
+ int cstart, uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3);
struct ir3_instruction * ir3_instr_create(struct ir3_shader *shader, int category, opc_t opc);
diff --git a/asm/lexer.l b/asm/lexer.l
index 6e92c0c..8067df1 100644
--- a/asm/lexer.l
+++ b/asm/lexer.l
@@ -70,10 +70,11 @@ static int parse_reg(const char *str)
[ \t] ; /* ignore whitespace */
";"[^\n]*"\n" yylineno++; /* ignore comments */
[0-9]+"."[0-9]+ asm_yylval.flt = strtod(yytext, NULL); return T_FLOAT;
-[0-9]* asm_yylval.num = strtol(yytext, NULL, 0); return T_INT;
-"0x"[0-9a-fA-F]* asm_yylval.num = strtol(yytext, NULL, 0); return T_HEX;
+[0-9]* asm_yylval.num = strtoul(yytext, NULL, 0); return T_INT;
+"0x"[0-9a-fA-F]* asm_yylval.num = strtoul(yytext, NULL, 0); return T_HEX;
"@out" return TOKEN(T_A_OUT);
"@in" return TOKEN(T_A_IN);
+"@const" return TOKEN(T_A_CONST);
"(sy)" return TOKEN(T_SY);
"(ss)" return TOKEN(T_SS);
"(absneg)" return TOKEN(T_ABSNEG);
diff --git a/asm/parser.y b/asm/parser.y
index 6e95b51..48661d6 100644
--- a/asm/parser.y
+++ b/asm/parser.y
@@ -143,6 +143,7 @@ struct ir3_shader * ir3_asm_parse(const char *src)
%union {
int tok;
int num;
+ uint32_t unum;
double flt;
const char *str;
struct ir3_register *reg;
@@ -159,15 +160,16 @@ static void print_token(FILE *file, int type, YYSTYPE value)
%}
%token <num> T_INT
-%token <num> T_HEX
+%token <unum> T_HEX
%token <flt> T_FLOAT
%token <str> T_IDENTIFIER
%token <num> T_REGISTER
%token <num> T_CONSTANT
-/* @ headers (@out/@in) */
+/* @ headers (@out/@in/@const) */
%token <tok> T_A_OUT
%token <tok> T_A_IN
+%token <tok> T_A_CONST
/* src register flags */
%token <tok> T_ABSNEG
@@ -382,6 +384,7 @@ static void print_token(FILE *file, int type, YYSTYPE value)
%type <tok> cat4_opc
%type <tok> cat5_opc cat5_samp cat5_tex cat5_type
%type <type> type
+%type <unum> const_val
%error-verbose
@@ -396,6 +399,7 @@ headers:
header: out_header
| in_header
+| const_header
out_header: T_A_OUT '(' T_REGISTER ')' T_IDENTIFIER {
ir3_out_create(shader, $3, $5);
@@ -404,6 +408,15 @@ in_header: T_A_IN '(' T_REGISTER ')' T_IDENTIFIER {
ir3_in_create(shader, $3, $5);
}
+const_val: T_FLOAT { $$ = fui($1); }
+| T_INT { $$ = $1; }
+| '-' T_INT { $$ = -$2; }
+| T_HEX { $$ = $1; }
+
+const_header: T_A_CONST '(' T_CONSTANT ')' const_val ',' const_val ',' const_val ',' const_val {
+ ir3_const_create(shader, $3, $5, $7, $9, $11);
+}
+
iflag: T_SY { iflags.flags |= IR3_INSTR_SY; }
| T_SS { iflags.flags |= IR3_INSTR_SS; }
| T_JP { iflags.flags |= IR3_INSTR_JP; }
diff --git a/ir3test.c b/ir3test.c
index 8799dff..630e2c7 100644
--- a/ir3test.c
+++ b/ir3test.c
@@ -80,9 +80,25 @@ static void shader_run(struct ir3_shader *shader,
float *outputs, float *regs)
{
static uint32_t dwords[64 * 1024];
+ static float actual_consts[ARRAY_SIZE(consts)];
uint32_t regs_count, half_regs_count;
unsigned i;
+ /* shadow the consts used by all shaders, and overlay correct
+ * immediate values, so that we can compare before/after shaders
+ * if one uses immediates encoded in instructions or immediates
+ * at a different const regs (ie. sysval const changes, etc)
+ */
+
+ memcpy(actual_consts, consts, sizeof(consts));
+ for (i = 0; i < shader->consts_count; i++) {
+ struct ir3_const *c = shader->consts[i];
+ actual_consts[c->cstart->num + 0] = uif(c->val[0]);
+ actual_consts[c->cstart->num + 1] = uif(c->val[1]);
+ actual_consts[c->cstart->num + 2] = uif(c->val[2]);
+ actual_consts[c->cstart->num + 3] = uif(c->val[3]);
+ }
+
ir3_shader_assemble(shader, dwords, ARRAY_SIZE(dwords), info);
assert(((info->max_const + 1) * 4) < ARRAY_SIZE(consts));
@@ -102,7 +118,7 @@ static void shader_run(struct ir3_shader *shader,
}
ir3_emu_run(dwords, shader->instrs_count,
- consts, (info->max_const + 1) * 4,
+ actual_consts, (info->max_const + 1) * 4,
regs, regs_count, half_regs_count);
/* copy output values back from registers: */
diff --git a/util.h b/util.h
index e538f82..65ebf9c 100644
--- a/util.h
+++ b/util.h
@@ -74,4 +74,14 @@ static inline uint32_t fui(float f)
return fi.ui;
}
+static inline float uif(uint32_t ui)
+{
+ union {
+ float f;
+ uint32_t ui;
+ } fi;
+ fi.ui = ui;
+ return fi.f;
+}
+
#endif /* UTIL_H_ */