mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-24 19:00:23 +01:00
label routines for implementing branches, jumps
This commit is contained in:
parent
0cc9419631
commit
d8d07b2a8a
2 changed files with 119 additions and 0 deletions
77
src/mesa/shader/slang/slang_label.c
Normal file
77
src/mesa/shader/slang/slang_label.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
42
src/mesa/shader/slang/slang_label.h
Normal file
42
src/mesa/shader/slang/slang_label.h
Normal file
|
|
@ -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 */
|
||||
Loading…
Add table
Reference in a new issue