diff options
author | Brian <[email protected]> | 2007-02-23 09:36:29 -0700 |
---|---|---|
committer | Brian <[email protected]> | 2007-02-23 09:36:29 -0700 |
commit | d8d07b2a8aa5cf9c5ce877b20351983b1aa8d01d (patch) | |
tree | 9956a9fe11d312caa204bd59890d61692338090b /src/mesa/shader | |
parent | 0cc941963197fcdf8913462dbb225bc2bfca9d85 (diff) |
label routines for implementing branches, jumps
Diffstat (limited to 'src/mesa/shader')
-rw-r--r-- | src/mesa/shader/slang/slang_label.c | 77 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_label.h | 42 |
2 files changed, 119 insertions, 0 deletions
diff --git a/src/mesa/shader/slang/slang_label.c b/src/mesa/shader/slang/slang_label.c new file mode 100644 index 00000000000..4d35d2e72a1 --- /dev/null +++ b/src/mesa/shader/slang/slang_label.c @@ -0,0 +1,77 @@ + + +/** + * Functions for managing instruction labels. + * Basically, this is used to manage the problem of forward branches where + * we have a branch instruciton but don't know the target address yet. + */ + + +#include "slang_label.h" + + +slang_label * +_slang_label_new(const char *name) +{ + slang_label *l = (slang_label *) _mesa_calloc(sizeof(slang_label)); + if (l) { + l->Name = _mesa_strdup(name); + l->Location = -1; + } + return l; +} + +void +_slang_label_delete(slang_label *l) +{ + if (l->Name) + _mesa_free(l->Name); + if (l->References) + _mesa_free(l->References); + _mesa_free(l); +} + + +void +_slang_label_add_reference(slang_label *l, GLuint inst) +{ + const GLuint oldSize = l->NumReferences * sizeof(GLuint); + assert(l->Location < 0); + l->References = _mesa_realloc(l->References, + oldSize, oldSize + sizeof(GLuint)); + if (l->References) { + l->References[l->NumReferences] = inst; + l->NumReferences++; + } +} + + +GLint +_slang_label_get_location(const slang_label *l) +{ + return l->Location; +} + + +void +_slang_label_set_location(slang_label *l, GLint location, + struct gl_program *prog) +{ + GLuint i; + + assert(l->Location < 0); + assert(location >= 0); + + l->Location = location; + + /* for the instructions that were waiting to learn the label's location: */ + for (i = 0; i < l->NumReferences; i++) { + const GLuint j = l->References[i]; + prog->Instructions[j].BranchTarget = location; + } + + if (l->References) { + _mesa_free(l->References); + l->References = NULL; + } +} diff --git a/src/mesa/shader/slang/slang_label.h b/src/mesa/shader/slang/slang_label.h new file mode 100644 index 00000000000..661624f173b --- /dev/null +++ b/src/mesa/shader/slang/slang_label.h @@ -0,0 +1,42 @@ +#ifndef SLANG_LABEL_H +#define SLANG_LABEL_H 1 + +#include "imports.h" +#include "mtypes.h" +#include "prog_instruction.h" + + +struct slang_label_ +{ + char *Name; + GLint Location; + /** + * List of instruction references (numbered starting at zero) which need + * their BranchTarget field filled in with the location eventually + * assigned to the label. + */ + GLuint NumReferences; + GLuint *References; /** Array [NumReferences] */ +}; + +typedef struct slang_label_ slang_label; + + +extern slang_label * +_slang_label_new(const char *name); + +extern void +_slang_label_delete(slang_label *l); + +extern void +_slang_label_add_reference(slang_label *l, GLuint inst); + +extern GLint +_slang_label_get_location(const slang_label *l); + +extern void +_slang_label_set_location(slang_label *l, GLint location, + struct gl_program *prog); + + +#endif /* SLANG_LABEL_H */ |