summaryrefslogtreecommitdiff
path: root/assembler
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2013-01-26 23:09:42 +0000
committerDamien Lespiau <damien.lespiau@intel.com>2013-03-04 15:54:40 +0000
commitd70e9f824f6f837614bbc2714c5ccc5f77d2c539 (patch)
tree5e9563c8fa58b63e64a1d6d19ba7c437b45dc0bd /assembler
parente9172aa22538216cd434c700d78915ec06142238 (diff)
assembler: Add a check for when width is 1 and hstride is not 0
The list of region restrictions in bspec do say that we can't have: width == 1 && hstrize != 0 We do have plenty of assembly code that don't respect that behaviour. So let's hide the warning under a -W flag (for now) while we fix things. Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Diffstat (limited to 'assembler')
-rw-r--r--assembler/gen4asm.h4
-rw-r--r--assembler/gram.y29
-rw-r--r--assembler/main.c7
3 files changed, 38 insertions, 2 deletions
diff --git a/assembler/gen4asm.h b/assembler/gen4asm.h
index 8db7bce2..1e67c1cd 100644
--- a/assembler/gen4asm.h
+++ b/assembler/gen4asm.h
@@ -43,6 +43,10 @@ typedef float GLfloat;
extern long int gen_level;
+#define WARN_ALWAYS (1 << 0)
+#define WARN_ALL (1 << 31)
+extern unsigned int warning_flags;
+
extern struct brw_context genasm_context;
extern struct brw_compile genasm_compile;
diff --git a/assembler/gram.y b/assembler/gram.y
index f27f6fe8..96bc7974 100644
--- a/assembler/gram.y
+++ b/assembler/gram.y
@@ -130,7 +130,12 @@ static void message(enum message_level level, YYLTYPE *location,
va_end(args);
}
-#define warn(l, fmt, ...) message(WARN, location, fmt, ## __VA_ARGS__)
+#define warn(flag, l, fmt, ...) \
+ do { \
+ if (warning_flags & WARN_ ## flag) \
+ message(WARN, location, fmt, ## __VA_ARGS__); \
+ } while(0)
+
#define error(l, fmt, ...) message(ERROR, location, fmt, ## __VA_ARGS__)
/* like strcmp, but handles NULL pointers */
@@ -255,6 +260,10 @@ static bool validate_src_reg(struct brw_instruction *insn,
struct brw_reg reg,
YYLTYPE *location)
{
+ int hstride_for_reg[] = {0, 1, 2, 4};
+ int width_for_reg[] = {1, 2, 4, 8, 16};
+ int width, hstride;
+
if (reg.file == BRW_IMMEDIATE_VALUE)
return true;
@@ -265,6 +274,24 @@ static bool validate_src_reg(struct brw_instruction *insn,
return false;
}
+ assert(reg.hstride >= 0 && reg.hstride < ARRAY_SIZE(hstride_for_reg));
+ hstride = hstride_for_reg[reg.hstride];
+
+ assert(reg.width >= 0 && reg.width < ARRAY_SIZE(width_for_reg));
+ width = width_for_reg[reg.width];
+
+ /* Register Region Restrictions */
+
+ /* D. If Width = 1, HorzStride must be 0 regardless of the values of
+ * ExecSize and VertStride.
+ *
+ * FIXME: In "advanced mode" hstride is set to 1, this is probably a bug
+ * to fix, but it changes the generated opcodes and thus needs validation.
+ */
+ if (width == 1 && hstride != 0)
+ warn(ALL, location, "region width is 1 but horizontal stride is %d "
+ " (should be 0)\n", hstride);
+
return true;
}
diff --git a/assembler/main.c b/assembler/main.c
index cfee749a..4fe13156 100644
--- a/assembler/main.c
+++ b/assembler/main.c
@@ -43,6 +43,7 @@ extern int errors;
long int gen_level = 40;
int advanced_flag = 0; /* 0: in unit of byte, 1: in unit of data element size */
+unsigned int warning_flags = WARN_ALWAYS;
int binary_like_output = 0; /* 0: default output style, 1: nice C-style output */
int need_export = 0;
char *input_filename = "<stdin>";
@@ -293,7 +294,7 @@ int main(int argc, char **argv)
char o;
void *mem_ctx;
- while ((o = getopt_long(argc, argv, "e:l:o:g:ab", longopts, NULL)) != -1) {
+ while ((o = getopt_long(argc, argv, "e:l:o:g:abW", longopts, NULL)) != -1) {
switch (o) {
case 'o':
if (strcmp(optarg, "-") != 0)
@@ -344,6 +345,10 @@ int main(int argc, char **argv)
entry_table_file = optarg;
break;
+ case 'W':
+ warning_flags |= WARN_ALL;
+ break;
+
default:
usage();
exit(1);