From: Tom Stellard <thomas.stell...@amd.com>

The assembly parser can be used to load r300 assembly dumps
and run them through any of the r300 compiler passes.
---
 .../r300/compiler/tests/omod_two_writers.test      |    5 +
 .../r300/compiler/tests/r300_compiler_tests.h      |    1 +
 .../tests/radeon_compiler_optimize_tests.c         |   33 +++--
 .../drivers/r300/compiler/tests/rc_test_helpers.c  |  162 +++++++++++++++++++-
 .../drivers/r300/compiler/tests/rc_test_helpers.h  |   16 ++
 5 files changed, 201 insertions(+), 16 deletions(-)
 create mode 100644 
src/gallium/drivers/r300/compiler/tests/omod_two_writers.test

diff --git a/src/gallium/drivers/r300/compiler/tests/omod_two_writers.test 
b/src/gallium/drivers/r300/compiler/tests/omod_two_writers.test
new file mode 100644
index 0000000..fb16bb0
--- /dev/null
+++ b/src/gallium/drivers/r300/compiler/tests/omod_two_writers.test
@@ -0,0 +1,5 @@
+RCP temp[0].x, const[1].x___;
+RCP temp[0].y, const[1]._y__;
+MUL temp[1].xy, const[0].xx__, temp[0].xy__;
+MOV output[0].xy, temp[1].xy;
+=
diff --git a/src/gallium/drivers/r300/compiler/tests/r300_compiler_tests.h 
b/src/gallium/drivers/r300/compiler/tests/r300_compiler_tests.h
index 266addf..d40834a 100644
--- a/src/gallium/drivers/r300/compiler/tests/r300_compiler_tests.h
+++ b/src/gallium/drivers/r300/compiler/tests/r300_compiler_tests.h
@@ -26,4 +26,5 @@
  */
 
 unsigned radeon_compiler_optimize_run_tests(void);
+unsigned radeon_compiler_regalloc_run_tests(void);
 unsigned radeon_compiler_util_run_tests(void);
diff --git 
a/src/gallium/drivers/r300/compiler/tests/radeon_compiler_optimize_tests.c 
b/src/gallium/drivers/r300/compiler/tests/radeon_compiler_optimize_tests.c
index 600228e..819fb6c 100644
--- a/src/gallium/drivers/r300/compiler/tests/radeon_compiler_optimize_tests.c
+++ b/src/gallium/drivers/r300/compiler/tests/radeon_compiler_optimize_tests.c
@@ -30,30 +30,42 @@
 #include "rc_test_helpers.h"
 #include "unit_test.h"
 
+static unsigned test_rc_optimize(
+       struct test_result * result,
+       struct radeon_compiler * c,
+       const char * filename)
+{
+       struct rc_test_file test_file;
+
+       test_begin(result);
+
+       if (!load_program(c, &test_file, filename)) {
+               fprintf(stderr, "Failed to load program\n");
+               return 0;
+       }
+
+       rc_optimize(c, NULL);
+       return 1;
+}
+
 static void test_runner_rc_optimize(struct test_result * result)
 {
+       unsigned pass = 1;
        struct radeon_compiler c;
        struct rc_instruction *inst;
        struct rc_instruction *inst_list[3];
        unsigned inst_count = 0;
        float const0[4] = {2.0f, 0.0f, 0.0f, 0.0f};
-       unsigned pass = 1;
 
-       test_begin(result);
        init_compiler(&c, RC_FRAGMENT_PROGRAM, 1, 0);
 
        rc_constants_add_immediate_vec4(&c.Program.Constants, const0);
 
-       add_instruction(&c, "RCP temp[0].x, const[1].x___;");
-       add_instruction(&c, "RCP temp[0].y, const[1]._y__;");
-       add_instruction(&c, "MUL temp[1].xy, const[0].xx__, temp[0].xy__;");
-       add_instruction(&c, "MOV output[0].xy, temp[1].xy;" );
-
-       rc_optimize(&c, NULL);
+       test_rc_optimize(result, &c, "omod_two_writers.test");
 
        for(inst = c.Program.Instructions.Next;
-                                       inst != &c.Program.Instructions;
-                                       inst = inst->Next, inst_count++) {
+                               inst != &c.Program.Instructions;
+                               inst = inst->Next, inst_count++) {
                inst_list[inst_count] = inst;
        }
 
@@ -62,6 +74,7 @@ static void test_runner_rc_optimize(struct test_result * 
result)
                        inst_list[2]->U.I.Opcode != RC_OPCODE_MOV) {
                pass = 0;
        }
+
        test_check(result, pass);
 }
 
diff --git a/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.c 
b/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.c
index 551fe05..9a171d3 100644
--- a/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.c
+++ b/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.c
@@ -42,6 +42,7 @@
 #include "radeon_program.h"
 #include "radeon_regalloc.h"
 #include "radeon_swizzle.h"
+#include "util/u_math.h"
 
 #include "rc_test_helpers.h"
 
@@ -61,6 +62,17 @@ struct match_info {
        int Length;
 };
 
+static int is_whitespace(const char *str)
+{
+       regex_t regex;
+       int err;
+       if (regcomp(&regex, "^[ \n]+$", REG_EXTENDED)) {
+               fprintf(stderr, "Failed to compile whitespace regex\n");
+               return 0;
+       }
+       return regexec(&regex, str, 0, NULL, 0) != REG_NOMATCH;
+}
+
 static int match_length(regmatch_t * matches, int index)
 {
        return matches[index].rm_eo - matches[index].rm_so;
@@ -124,7 +136,7 @@ int init_rc_normal_src(
        unsigned int src_index,
        const char * src_str)
 {
-       const char * regex_str = 
"(-*)(\\|*)([[:lower:]]*)\\[([[:digit:]])\\](\\.*[[:lower:]-]*)";
+       const char * regex_str = 
"(-*)(\\|*)([[:lower:]]*)\\[*([[:digit:]]*)\\]*(\\.*[[:lower:]_]*)";
        regmatch_t matches[REGEX_SRC_MATCHES];
        struct src_tokens tokens;
        struct rc_src_register * src_reg = &inst->U.I.SrcReg[src_index];
@@ -187,7 +199,8 @@ int init_rc_normal_src(
                        fprintf(stderr, "First char of swizzle is not 
valid.\n");
                        return 0;
                }
-               for (i = 0; i < 4; i++, str_index++) {
+               for (i = 0; i < 4 && str_index < tokens.Swizzle.Length;
+                                                       i++, str_index++) {
                        if (tokens.Swizzle.String[str_index] == '-') {
                                src_reg->Negate |= (1 << i);
                                str_index++;
@@ -218,7 +231,8 @@ int init_rc_normal_src(
                                SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_UNUSED);
                                break;
                        default:
-                               fprintf(stderr, "Unknown src register 
swizzle.\n");
+                               fprintf(stderr, "Unknown src register swizzle: 
%c\n",
+                                               
tokens.Swizzle.String[str_index]);
                                return 0;
                        }
                }
@@ -251,7 +265,7 @@ int init_rc_normal_dst(
        struct rc_instruction * inst,
        const char * dst_str)
 {
-       const char * regex_str = 
"([[:lower:]]*)\\[([[:digit:]]*)\\](\\.*[[:lower:]]*)";
+       const char * regex_str = 
"([[:lower:]]*)\\[*([[:digit:]]*)\\]*(\\.*[[:lower:]]*)";
        regmatch_t matches[REGEX_DST_MATCHES];
        struct dst_tokens tokens;
        unsigned int i;
@@ -275,6 +289,9 @@ int init_rc_normal_dst(
                inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
        } else if (!strncmp(tokens.File.String, "output", tokens.File.Length)) {
                inst->U.I.DstReg.File = RC_FILE_OUTPUT;
+       } else if (!strncmp(tokens.File.String, "none", tokens.File.Length)) {
+               inst->U.I.DstReg.File = RC_FILE_NONE;
+               return 1;
        } else {
                fprintf(stderr, "Unknown dst register file type.\n");
                return 0;
@@ -314,7 +331,8 @@ int init_rc_normal_dst(
                                inst->U.I.DstReg.WriteMask |= RC_MASK_W;
                                break;
                        default:
-                               fprintf(stderr, "Unknown swizzle in 
writemask.\n");
+                               fprintf(stderr, "Unknown swizzle in writemask: 
%c\n",
+                                                       
tokens.WriteMask.String[i]);
                                return 0;
                        }
                }
@@ -327,6 +345,7 @@ int init_rc_normal_dst(
 }
 
 #define REGEX_INST_MATCHES 7
+#define REGEX_CONST_MATCHES 5
 
 struct inst_tokens {
        struct match_info Opcode;
@@ -351,7 +370,7 @@ int parse_rc_normal_instruction(
        struct rc_instruction * inst,
        const char * inst_str)
 {
-       const char * regex_str = "([[:upper:]]+)(_SAT)* ([^,]*)[, ]*([^,]*)[, 
]*([^,]*)[, ]*([^;]*)";
+       const char * regex_str = "[[:digit:]: ]*([[:upper:][:digit:]]+)(_SAT)*[ 
]*([^,;]*)[, ]*([^,;]*)[, ]*([^,;]*)[, ]*([^;]*)";
        int i;
        regmatch_t matches[REGEX_INST_MATCHES];
        struct inst_tokens tokens;
@@ -408,11 +427,24 @@ int parse_rc_normal_instruction(
                        src_str[tokens.Srcs[j].Length] = '\0';
                        init_rc_normal_src(inst, j, src_str);
                }
+               if (info->HasTexture) {
+                       /* XXX: Will this always be XYZW ? */
+                       inst->U.I.TexSwizzle = RC_SWIZZLE_XYZW;
+               }
                break;
        }
        return 1;
 }
 
+#define INDEX_TOKEN_LEN 4
+#define FLOAT_TOKEN_LEN 50
+int parse_constant(unsigned *index, float *data, const char *const_str)
+{
+       int matched = sscanf(const_str, "const[%d] {%f, %f, %f, %f}", index,
+                               &data[0], &data[1], &data[2], &data[3]);
+       return matched == 5;
+}
+
 int init_rc_normal_instruction(
        struct rc_instruction * inst,
        const char * inst_str)
@@ -432,6 +464,44 @@ void add_instruction(struct radeon_compiler *c, const char 
* inst_string)
 
 }
 
+int add_constant(struct radeon_compiler *c, const char *const_str)
+{
+       float data[4];
+       unsigned index;
+       struct rc_constant_list *constants;
+       struct rc_constant constant;
+
+       if (!parse_constant(&index, data, const_str)) {
+               return 0;
+       }
+
+       constants = &c->Program.Constants;
+       if (constants->_Reserved < index) {
+               struct rc_constant * newlist;
+
+               constants->_Reserved = index + 100;
+
+               newlist = malloc(sizeof(struct rc_constant) * 
constants->_Reserved);
+               if (constants->Constants) {
+                       memcpy(newlist, constants->Constants,
+                               sizeof(struct rc_constant) *
+                                       constants->_Reserved);
+                       free(constants->Constants);
+               }
+
+               constants->Constants = newlist;
+       }
+
+       memset(&constant, 0, sizeof(constant));
+       constant.Type = RC_CONSTANT_IMMEDIATE;
+       constant.Size = 4;
+       memcpy(constant.u.Immediate, data, sizeof(float) * 4);
+       constants->Constants[index] = constant;
+       constants->Count = MAX2(constants->Count, index + 1);
+
+       return 1;
+}
+
 void init_compiler(
        struct radeon_compiler *c,
        enum rc_program_type program_type,
@@ -439,6 +509,7 @@ void init_compiler(
        unsigned is_r400)
 {
        struct rc_regalloc_state *rs = malloc(sizeof(struct rc_regalloc_state));
+       rc_init_regalloc_state(rs);
        rc_init(c, rs);
 
        c->is_r500 = is_r500;
@@ -456,3 +527,82 @@ void init_compiler(
                c->SwizzleCaps = &r300_vertprog_swizzle_caps;
        }
 }
+
+#define MAX_LINE_LENGTH 100
+#define MAX_PATH_LENGTH 100
+
+unsigned load_program(
+       struct radeon_compiler *c,
+       struct rc_test_file *test,
+       const char *filename)
+{
+       char line[MAX_LINE_LENGTH];
+       char path[MAX_PATH_LENGTH];
+       FILE *file;
+       unsigned *count;
+       char **string_store;
+       unsigned i = 0;
+
+       snprintf(path, MAX_PATH_LENGTH, "compiler/tests/%s", filename);
+       file = fopen(path, "r");
+       if (!file) {
+               return 0;
+       }
+       memset(test, 0, sizeof(struct rc_test_file));
+
+       count = &test->num_input_lines;
+
+       while (fgets(line, MAX_LINE_LENGTH, file)){
+               if (line[MAX_LINE_LENGTH - 2] == '\n') {
+                       fprintf(stderr, "Error line cannot be longer than 100 "
+                               "characters:\n%s\n", line);
+                       return 0;
+               }
+
+               // Comment
+               if (line[0] == '#' || is_whitespace(line)) {
+                       continue;
+               }
+
+               if (line[0] == '=') {
+                       count = &test->num_expected_lines;
+                       continue;
+               }
+
+               (*count)++;
+       }
+
+       test->input = malloc(sizeof(char *) * test->num_input_lines);
+       test->expected = malloc(sizeof(char *) * test->num_expected_lines);
+
+       rewind(file);
+       string_store = test->input;
+
+       while(fgets(line, MAX_LINE_LENGTH, file)) {
+               // Comment
+               char * dst;
+               if (line[0] == '#' || is_whitespace(line)) {
+                       continue;
+               }
+
+               if (line[0] == '=') {
+                       i = 0;
+                       string_store = test->expected;
+                       continue;
+               }
+
+               dst = string_store[i++] = malloc((strlen(line) + 1) *
+                                                       sizeof (char));
+               strcpy(dst, line);
+       }
+
+       for (i = 0; i < test->num_input_lines; i++) {
+               if (test->input[i][0] == 'c') {
+                       add_constant(c, test->input[i]);
+                       continue;
+               }
+               // XXX: Parse immediates from the file.
+               add_instruction(c, test->input[i]);
+       }
+       return 1;
+}
diff --git a/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.h 
b/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.h
index 49a46a9..6cc8d9c 100644
--- a/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.h
+++ b/src/gallium/drivers/r300/compiler/tests/rc_test_helpers.h
@@ -29,6 +29,13 @@
 
 #include "radeon_compiler.h"
 
+struct rc_test_file {
+       unsigned num_input_lines;
+       char **input;
+       unsigned num_expected_lines;
+       char **expected;
+};
+
 int init_rc_normal_src(
        struct rc_instruction * inst,
        unsigned int src_index,
@@ -42,14 +49,23 @@ int parse_rc_normal_instruction(
        struct rc_instruction * inst,
        const char * inst_str);
 
+int parse_constant(unsigned *index, float *data, const char *const_str);
+
 int init_rc_normal_instruction(
        struct rc_instruction * inst,
        const char * inst_str);
 
 void add_instruction(struct radeon_compiler *c, const char * inst_string);
 
+int add_constant(struct radeon_compiler *c, const char *const_str);
+
 void init_compiler(
        struct radeon_compiler *c,
        enum rc_program_type program_type,
        unsigned is_r500,
        unsigned is_r400);
+
+unsigned load_program(
+       struct radeon_compiler *c,
+       struct rc_test_file *test,
+       const char *filename);
-- 
1.7.3.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to