aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/shader/slang/slang_label.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-10-09 06:31:44 +0000
committermarha <marha@users.sourceforge.net>2009-10-09 06:31:44 +0000
commit06456f5db88b434c3634ede42bdbfdce78fc4249 (patch)
tree97f5174e2d3da40faee7f2ad8858233da3d0166e /mesalib/src/mesa/shader/slang/slang_label.c
parent7b230a3fe2d6c83488d9eec43067fe8ba8ac081b (diff)
parenta0c4815433ccd57322f4f7703ca35e9ccfa59250 (diff)
downloadvcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.tar.gz
vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.tar.bz2
vcxsrv-06456f5db88b434c3634ede42bdbfdce78fc4249.zip
svn merge ^/branches/released . --username marha
Diffstat (limited to 'mesalib/src/mesa/shader/slang/slang_label.c')
-rw-r--r--mesalib/src/mesa/shader/slang/slang_label.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/mesalib/src/mesa/shader/slang/slang_label.c b/mesalib/src/mesa/shader/slang/slang_label.c
new file mode 100644
index 000000000..1ca1ef0c7
--- /dev/null
+++ b/mesalib/src/mesa/shader/slang/slang_label.c
@@ -0,0 +1,104 @@
+
+
+/**
+ * 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"
+#include "slang_mem.h"
+
+
+
+slang_label *
+_slang_label_new(const char *name)
+{
+ slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
+ if (l) {
+ l->Name = _slang_strdup(name);
+ l->Location = -1;
+ }
+ return l;
+}
+
+/**
+ * As above, but suffix the name with a unique number.
+ */
+slang_label *
+_slang_label_new_unique(const char *name)
+{
+ static int id = 1;
+ slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
+ if (l) {
+ l->Name = (char *) _slang_alloc(_mesa_strlen(name) + 10);
+ if (!l->Name) {
+ _mesa_free(l);
+ return NULL;
+ }
+ _mesa_sprintf(l->Name, "%s_%d", name, id);
+ id++;
+ l->Location = -1;
+ }
+ return l;
+}
+
+void
+_slang_label_delete(slang_label *l)
+{
+ if (l->Name) {
+ _slang_free(l->Name);
+ l->Name = NULL;
+ }
+ if (l->References) {
+ _slang_free(l->References);
+ l->References = NULL;
+ }
+ _slang_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 = _slang_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) {
+ _slang_free(l->References);
+ l->References = NULL;
+ }
+}