merge of glsl-compiler-1 branch
[mesa.git] / src / mesa / shader / slang / slang_label.c
1
2
3 /**
4 * Functions for managing instruction labels.
5 * Basically, this is used to manage the problem of forward branches where
6 * we have a branch instruciton but don't know the target address yet.
7 */
8
9
10 #include "slang_label.h"
11
12
13 slang_label *
14 _slang_label_new(const char *name)
15 {
16 slang_label *l = (slang_label *) _mesa_calloc(sizeof(slang_label));
17 if (l) {
18 l->Name = _mesa_strdup(name);
19 l->Location = -1;
20 }
21 return l;
22 }
23
24 void
25 _slang_label_delete(slang_label *l)
26 {
27 if (l->Name)
28 _mesa_free(l->Name);
29 if (l->References)
30 _mesa_free(l->References);
31 _mesa_free(l);
32 }
33
34
35 void
36 _slang_label_add_reference(slang_label *l, GLuint inst)
37 {
38 const GLuint oldSize = l->NumReferences * sizeof(GLuint);
39 assert(l->Location < 0);
40 l->References = _mesa_realloc(l->References,
41 oldSize, oldSize + sizeof(GLuint));
42 if (l->References) {
43 l->References[l->NumReferences] = inst;
44 l->NumReferences++;
45 }
46 }
47
48
49 GLint
50 _slang_label_get_location(const slang_label *l)
51 {
52 return l->Location;
53 }
54
55
56 void
57 _slang_label_set_location(slang_label *l, GLint location,
58 struct gl_program *prog)
59 {
60 GLuint i;
61
62 assert(l->Location < 0);
63 assert(location >= 0);
64
65 l->Location = location;
66
67 /* for the instructions that were waiting to learn the label's location: */
68 for (i = 0; i < l->NumReferences; i++) {
69 const GLuint j = l->References[i];
70 prog->Instructions[j].BranchTarget = location;
71 }
72
73 if (l->References) {
74 _mesa_free(l->References);
75 l->References = NULL;
76 }
77 }