[PATCH 59/90] assembler: Add a check for when width is 1 and hstride is not 0

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 at intel.com>
---
 assembler/gen4asm.h |    4 ++++
 assembler/gram.y    |   29 ++++++++++++++++++++++++++++-
 assembler/main.c    |    7 ++++++-
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/assembler/gen4asm.h b/assembler/gen4asm.h
index 8db7bce..1e67c1c 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 f27f6fe..96bc797 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 cfee749..4fe1315 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);
-- 
1.7.7.5



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux