summaryrefslogtreecommitdiff
path: root/src/mesa/shader/slang/slang_assemble.c
diff options
context:
space:
mode:
authorMichal Krol <mjkrol@gmail.org>2006-02-13 11:38:37 +0000
committerMichal Krol <mjkrol@gmail.org>2006-02-13 11:38:37 +0000
commit02eb9acc5e4307db09662592951ef44319a0cda5 (patch)
tree585a539ed6d6775801dcc9e685759521680da9f9 /src/mesa/shader/slang/slang_assemble.c
parent44e9ccc708bb0a92dfeaf038ded60295dfe2d3ae (diff)
Get it running for ARB_vertex_shader.
Add experimental print functions to builtin library. Some functionality missing: - automatic arrays; - general constructors; - local variable initialization; - texture sampling and noise; - semantic error checking; - function prototypes.
Diffstat (limited to 'src/mesa/shader/slang/slang_assemble.c')
-rw-r--r--src/mesa/shader/slang/slang_assemble.c1061
1 files changed, 639 insertions, 422 deletions
diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c
index a97da6b283..45b6b1961c 100644
--- a/src/mesa/shader/slang/slang_assemble.c
+++ b/src/mesa/shader/slang/slang_assemble.c
@@ -31,18 +31,20 @@
#include "imports.h"
#include "slang_utility.h"
#include "slang_assemble.h"
-#include "slang_compile.h"
+/*#include "slang_compile.h"*/
#include "slang_storage.h"
-#include "slang_assemble_constructor.h"
+/*#include "slang_assemble_constructor.h"*/
#include "slang_assemble_typeinfo.h"
#include "slang_assemble_conditional.h"
#include "slang_assemble_assignment.h"
+#include "slang_execute.h"
/* slang_assembly */
-static void slang_assembly_construct (slang_assembly *assem)
+static int slang_assembly_construct (slang_assembly *assem)
{
assem->type = slang_asm_none;
+ return 1;
}
static void slang_assembly_destruct (slang_assembly *assem)
@@ -51,10 +53,12 @@ static void slang_assembly_destruct (slang_assembly *assem)
/* slang_assembly_file */
-void slang_assembly_file_construct (slang_assembly_file *file)
+int slang_assembly_file_construct (slang_assembly_file *file)
{
file->code = NULL;
file->count = 0;
+ file->capacity = 0;
+ return 1;
}
void slang_assembly_file_destruct (slang_assembly_file *file)
@@ -62,30 +66,40 @@ void slang_assembly_file_destruct (slang_assembly_file *file)
unsigned int i;
for (i = 0; i < file->count; i++)
- slang_assembly_destruct (file->code + i);
+ slang_assembly_destruct (&file->code[i]);
slang_alloc_free (file->code);
}
-static int slang_assembly_file_push_new (slang_assembly_file *file)
+static int push_new (slang_assembly_file *file)
{
- file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof (
- slang_assembly), (file->count + 1) * sizeof (slang_assembly));
- if (file->code != NULL)
+ if (file->count == file->capacity)
{
- slang_assembly_construct (file->code + file->count);
- file->count++;
- return 1;
+ unsigned int n;
+
+ if (file->capacity == 0)
+ n = 256;
+ else
+ n = file->capacity * 2;
+ file->code = (slang_assembly *) slang_alloc_realloc (file->code,
+ file->capacity * sizeof (slang_assembly), n * sizeof (slang_assembly));
+ if (file->code == NULL)
+ return 0;
+ file->capacity = n;
}
- return 0;
+ if (!slang_assembly_construct (&file->code[file->count]))
+ return 0;
+ file->count++;
+ return 1;
}
-static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type,
- GLfloat literal, GLuint label, GLuint size)
+static int push_gen (slang_assembly_file *file, slang_assembly_type type, GLfloat literal,
+ GLuint label, GLuint size)
{
slang_assembly *assem;
- if (!slang_assembly_file_push_new (file))
+
+ if (!push_new (file))
return 0;
- assem = file->code + file->count - 1;
+ assem = &file->code[file->count - 1];
assem->type = type;
assem->literal = literal;
assem->param[0] = label;
@@ -95,102 +109,138 @@ static int slang_assembly_file_push_general (slang_assembly_file *file, slang_as
int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type)
{
- return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0);
+ return push_gen (file, type, (GLfloat) 0, 0, 0);
}
int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type,
GLuint label)
{
- return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0);
+ return push_gen (file, type, (GLfloat) 0, label, 0);
}
int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type,
GLuint label1, GLuint label2)
{
- return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2);
+ return push_gen (file, type, (GLfloat) 0, label1, label2);
}
int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type,
GLfloat literal)
{
- return slang_assembly_file_push_general (file, type, literal, 0, 0);
+ return push_gen (file, type, literal, 0, 0);
+}
+
+#define PUSH slang_assembly_file_push
+#define PLAB slang_assembly_file_push_label
+#define PLAB2 slang_assembly_file_push_label2
+#define PLIT slang_assembly_file_push_literal
+
+/* slang_assembly_file_restore_point */
+
+int slang_assembly_file_restore_point_save (slang_assembly_file *file,
+ slang_assembly_file_restore_point *point)
+{
+ point->count = file->count;
+ return 1;
+}
+
+int slang_assembly_file_restore_point_load (slang_assembly_file *file,
+ slang_assembly_file_restore_point *point)
+{
+ unsigned int i;
+
+ for (i = point->count; i < file->count; i++)
+ slang_assembly_destruct (&file->code[i]);
+ file->count = point->count;
+ return 1;
}
/* utility functions */
static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual,
- slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size)
+ slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size,
+ slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)
{
slang_storage_aggregate agg;
- slang_storage_aggregate_construct (&agg);
- if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs, space->vars))
+ /* calculate the size of the variable's aggregate */
+ if (!slang_storage_aggregate_construct (&agg))
+ return 0;
+ if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs,
+ space->vars, mach, pfile, atoms))
{
slang_storage_aggregate_destruct (&agg);
return 0;
}
*size += _slang_sizeof_aggregate (&agg);
+ slang_storage_aggregate_destruct (&agg);
+
+ /* for reference variables consider the additional address overhead */
if (qual == slang_qual_out || qual == slang_qual_inout)
*size += 4;
- slang_storage_aggregate_destruct (&agg);
return 1;
}
static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space,
- unsigned int *size)
+ unsigned int *size, slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)
{
var->address = *size;
if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout)
var->address += 4;
return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space,
- size);
+ size, mach, pfile, atoms);
}
static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop,
- slang_assembly_name_space *space, unsigned int *size)
+ slang_assembly_name_space *space, unsigned int *size, slang_machine *mach,
+ slang_assembly_file *pfile, slang_atom_pool *atoms)
{
unsigned int i;
for (i = start; i < stop; i++)
- if (!sizeof_variable2 (vars->variables + i, space, size))
+ if (!sizeof_variable2 (&vars->variables[i], space, size, mach, pfile, atoms))
return 0;
return 1;
}
static int collect_locals (slang_operation *op, slang_assembly_name_space *space,
- unsigned int *size)
+ unsigned int *size, slang_machine *mach, slang_assembly_file *pfile, slang_atom_pool *atoms)
{
unsigned int i;
- if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size))
+ if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size, mach, pfile,
+ atoms))
return 0;
for (i = 0; i < op->num_children; i++)
- if (!collect_locals (op->children + i, space, size))
+ if (!collect_locals (&op->children[i], space, size, mach, pfile, atoms))
return 0;
return 1;
}
/* _slang_locate_function() */
-slang_function *_slang_locate_function (const char *name, slang_operation *params,
- unsigned int num_params, slang_assembly_name_space *space)
+slang_function *_slang_locate_function (slang_function_scope *funcs, slang_atom a_name,
+ slang_operation *params, unsigned int num_params, slang_assembly_name_space *space,
+ slang_atom_pool *atoms)
{
unsigned int i;
- for (i = 0; i < space->funcs->num_functions; i++)
+ for (i = 0; i < funcs->num_functions; i++)
{
unsigned int j;
- slang_function *f = space->funcs->functions + i;
+ slang_function *f = &funcs->functions[i];
- if (slang_string_compare (name, f->header.name) != 0)
+ if (a_name != f->header.a_name)
continue;
if (f->param_count != num_params)
continue;
for (j = 0; j < num_params; j++)
{
slang_assembly_typeinfo ti;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (params + j, space, &ti))
+
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (&params[j], space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
@@ -201,28 +251,25 @@ slang_function *_slang_locate_function (const char *name, slang_operation *param
break;
}
slang_assembly_typeinfo_destruct (&ti);
+
/* "out" and "inout" formal parameter requires the actual parameter to be l-value */
if (!ti.can_be_referenced &&
- (f->parameters->variables[j].type.qualifier == slang_qual_out ||
- f->parameters->variables[j].type.qualifier == slang_qual_inout))
+ (f->parameters->variables[j].type.qualifier == slang_qual_out ||
+ f->parameters->variables[j].type.qualifier == slang_qual_inout))
break;
}
if (j == num_params)
return f;
}
- if (space->funcs->outer_scope != NULL)
- {
- slang_assembly_name_space my_space = *space;
- my_space.funcs = space->funcs->outer_scope;
- return _slang_locate_function (name, params, num_params, &my_space);
- }
+ if (funcs->outer_scope != NULL)
+ return _slang_locate_function (funcs->outer_scope, a_name, params, num_params, space, atoms);
return NULL;
}
/* _slang_assemble_function() */
int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
- slang_assembly_name_space *space)
+ slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)
{
unsigned int param_size, local_size;
unsigned int skip, cleanup;
@@ -238,97 +285,106 @@ int _slang_assemble_function (slang_assembly_file *file, slang_function *fun,
return 1;
}
- /* calculate return value and parameters size */
+ /* At this point traverse function formal parameters and code to calculate
+ * total memory size to be allocated on the stack.
+ * During this process the variables will be assigned local addresses to
+ * reference them in the code.
+ * No storage optimizations are performed so exclusive scopes are not detected and shared. */
+
+ /* calculate return value size */
param_size = 0;
if (fun->header.type.specifier.type != slang_spec_void)
if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
- &param_size))
+ &param_size, mach, file, atoms))
return 0;
info.ret_size = param_size;
- if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size))
+
+ /* calculate formal parameter list size */
+ if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, &param_size, mach, file,
+ atoms))
return 0;
- /* calculate local variables size, take into account the four-byte return address and
- temporaries for various tasks */
+ /* calculate local variables size - take into account the four-byte return address and
+ * temporaries for various tasks (4 for addr and 16 for swizzle temporaries).
+ * these include variables from the formal parameter scope and from the code */
info.addr_tmp = param_size + 4;
info.swizzle_tmp = param_size + 4 + 4;
local_size = param_size + 4 + 4 + 16;
if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space,
- &local_size))
+ &local_size, mach, file, atoms))
return 0;
- if (!collect_locals (fun->body, space, &local_size))
+ if (!collect_locals (fun->body, space, &local_size, mach, file, atoms))
return 0;
/* allocate local variable storage */
- if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4))
+ if (!PLAB (file, slang_asm_local_alloc, local_size - param_size - 4))
return 0;
/* mark a new frame for function variable storage */
- if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size))
+ if (!PLAB (file, slang_asm_enter, local_size))
return 0;
- /* skip the cleanup jump */
+ /* jump directly to the actual code */
skip = file->count;
- if (!slang_assembly_file_push_new (file))
+ if (!push_new (file))
return 0;
file->code[skip].type = slang_asm_jump;
/* all "return" statements will be directed here */
flow.function_end = file->count;
cleanup = file->count;
- if (!slang_assembly_file_push_new (file))
+ if (!push_new (file))
return 0;
file->code[cleanup].type = slang_asm_jump;
/* execute the function body */
file->code[skip].param[0] = file->count;
- if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk))
+ if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk, mach, atoms))
return 0;
/* this is the end of the function - restore the old function frame */
file->code[cleanup].param[0] = file->count;
- if (!slang_assembly_file_push (file, slang_asm_leave))
+ if (!PUSH (file, slang_asm_leave))
return 0;
/* free local variable storage */
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4))
+ if (!PLAB (file, slang_asm_local_free, local_size - param_size - 4))
return 0;
- /* jump out of the function */
- if (!slang_assembly_file_push (file, slang_asm_return))
+ /* return from the function */
+ if (!PUSH (file, slang_asm_return))
return 0;
return 1;
}
int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref,
- slang_assembly_name_space *space)
+ slang_assembly_name_space *space, slang_machine *mach, slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
- unsigned int size;
+ unsigned int size = 0;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
+ /* get type info of the operation and calculate its size */
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- if (ti.spec.type == slang_spec_void)
- size = 0;
- else if (ref)
+ if (ref)
size = 4;
- else
- {
- size = 0;
- if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size))
+ else if (ti.spec.type != slang_spec_void)
+ if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size, mach, file, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- }
slang_assembly_typeinfo_destruct (&ti);
+
+ /* if nonzero, free it from the stack */
if (size != 0)
{
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, size))
+ if (!PLAB (file, slang_asm_local_free, size))
return 0;
}
return 1;
@@ -336,103 +392,133 @@ int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int re
/* _slang_assemble_operation() */
-/* XXX: general swizzle! */
static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
- unsigned int index, unsigned int *size, slang_assembly_local_info *info)
+ unsigned int *size, slang_assembly_local_info *info, slang_swizzle *swz, int is_swizzled)
{
unsigned int i;
for (i = agg->count; i > 0; i--)
{
- const slang_storage_array *arr = agg->arrays + i - 1;
+ const slang_storage_array *arr = &agg->arrays[i - 1];
unsigned int j;
for (j = arr->length; j > 0; j--)
{
if (arr->type == slang_stor_aggregate)
{
- if (!dereference_aggregate (file, arr->aggregate, index, size, info))
+ if (!dereference_aggregate (file, arr->aggregate, size, info, swz, is_swizzled))
return 0;
}
else
{
+ unsigned int src_offset;
+ slang_assembly_type ty;
+
*size -= 4;
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
- 4))
+
+ /* calculate the offset within source variable to read */
+ if (is_swizzled)
+ {
+ /* swizzle the index to get the actual offset */
+ src_offset = swz->swizzle[*size / 4] * 4;
+ }
+ else
+ {
+ /* no swizzling - read sequentially */
+ src_offset = *size;
+ }
+
+ /* dereference data slot of a basic type */
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))
+ if (!PUSH (file, slang_asm_addr_deref))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size))
+ if (!PLAB (file, slang_asm_addr_push, src_offset))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_add))
+ if (!PUSH (file, slang_asm_addr_add))
return 0;
+
switch (arr->type)
{
case slang_stor_bool:
- if (!slang_assembly_file_push (file, slang_asm_bool_deref))
- return 0;
+ ty = slang_asm_bool_deref;
break;
case slang_stor_int:
- if (!slang_assembly_file_push (file, slang_asm_int_deref))
- return 0;
+ ty = slang_asm_int_deref;
break;
case slang_stor_float:
- if (!slang_assembly_file_push (file, slang_asm_float_deref))
- return 0;
+ ty = slang_asm_float_deref;
break;
}
- index += 4;
+ if (!PUSH (file, ty))
+ return 0;
}
}
}
return 1;
}
-/* XXX: general swizzle! */
-int dereference (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info)
+
+int _slang_dereference (slang_assembly_file *file, slang_operation *op,
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_machine *mach,
+ slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
int result;
slang_storage_aggregate agg;
unsigned int size;
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
+ /* get type information of the given operation */
+ if (!slang_assembly_typeinfo_construct (&ti))
+ return 0;
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
{
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
- slang_storage_aggregate_construct (&agg);
- if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs, space->vars))
+ /* construct aggregate from the type info */
+ if (!slang_storage_aggregate_construct (&agg))
+ {
+ slang_assembly_typeinfo_destruct (&ti);
+ return 0;
+ }
+ if (!_slang_aggregate_variable (&agg, &ti.spec, ti.array_size, space->funcs, space->structs,
+ space->vars, mach, file, atoms))
{
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return 0;
}
+ /* dereference the resulting aggregate */
size = _slang_sizeof_aggregate (&agg);
- result = dereference_aggregate (file, &agg, 0, &size, info);
+ result = dereference_aggregate (file, &agg, &size, info, &ti.swz, ti.is_swizzled);
slang_storage_aggregate_destruct (&agg);
slang_assembly_typeinfo_destruct (&ti);
return result;
}
-static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
+int _slang_call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
unsigned int i;
- slang_assembly_stack_info stk;
+ slang_assembly_stack_info p_stk[64];
+
+ /* TODO: fix this, allocate dynamically */
+ if (param_count > 64)
+ return 0;
/* make room for the return value, if any */
if (fun->header.type.specifier.type != slang_spec_void)
{
unsigned int ret_size = 0;
- if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size))
+
+ if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space,
+ &ret_size, mach, file, atoms))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size))
+ if (!PLAB (file, slang_asm_local_alloc, ret_size))
return 0;
}
@@ -444,56 +530,59 @@ static int call_function (slang_assembly_file *file, slang_function *fun, slang_
if (fun->parameters->variables[i].type.qualifier == slang_qual_inout ||
fun->parameters->variables[i].type.qualifier == slang_qual_out)
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
/* TODO: optimize the "out" parameter case */
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &params[i], 1, &flow, space, info, &p_stk[i],
+ mach, atoms))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_copy))
+ if (!PUSH (file, slang_asm_addr_copy))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))
+ if (!PUSH (file, slang_asm_addr_deref))
return 0;
if (i == 0 && assignment)
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp,
- 4))
+ /* duplicate the resulting address */
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
return 0;
- if (!slang_assembly_file_push (file, slang_asm_addr_deref))
+ if (!PUSH (file, slang_asm_addr_deref))
return 0;
}
- if (!dereference (file, params, space, info))
+ if (!_slang_dereference (file, &params[i], space, info, mach, atoms))
return 0;
}
else
{
- /* TODO: for "out" and "inout" parameters also push the address (first) */
- /* TODO: optimize the "out" parameter case */
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &params[i], 0, &flow, space, info, &p_stk[i],
+ mach, atoms))
return 0;
}
}
/* call the function */
- if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address))
+ if (!PLAB (file, slang_asm_call, fun->address))
return 0;
/* pop the parameters from the stack */
for (i = param_count; i > 0; i--)
{
unsigned int j = i - 1;
+
if (fun->parameters->variables[j].type.qualifier == slang_qual_inout ||
fun->parameters->variables[j].type.qualifier == slang_qual_out)
{
- if (!_slang_assemble_assignment (file, params + j, space, info))
+ /* for output parameter copy the contents of the formal parameter
+ * back to the original actual parameter */
+ if (!_slang_assemble_assignment (file, &params[j], space, info, &p_stk[j], mach, atoms))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+ /* pop the actual parameter's address */
+ if (!PLAB (file, slang_asm_local_free, 4))
return 0;
}
else
{
- if (!_slang_cleanup_stack (file, params + j, 0, space))
+ /* pop the value of the parameter */
+ if (!_slang_cleanup_stack (file, &params[j], 0, space, mach, atoms))
return 0;
}
}
@@ -501,73 +590,94 @@ static int call_function (slang_assembly_file *file, slang_function *fun, slang_
return 1;
}
+/* TODO: migrate to full-atom version */
int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params,
unsigned int param_count, int assignment, slang_assembly_name_space *space,
- slang_assembly_local_info *info)
+ slang_assembly_local_info *info, slang_machine *mach, slang_atom_pool *atoms)
{
- slang_function *fun = _slang_locate_function (name, params, param_count, space);
+ slang_atom atom;
+ slang_function *fun;
+
+ atom = slang_atom_pool_atom (atoms, name);
+ if (atom == SLANG_ATOM_NULL)
+ return 0;
+ fun = _slang_locate_function (space->funcs, atom, params, param_count, space, atoms);
if (fun == NULL)
return 0;
- return call_function (file, fun, params, param_count, assignment, space, info);
+ return _slang_call_function (file, fun, params, param_count, assignment, space, info, mach,
+ atoms);
}
static int call_function_name_dummyint (slang_assembly_file *file, const char *name,
- slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info)
+ slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info,
+ slang_machine *mach, slang_atom_pool *atoms)
{
- slang_operation p2[2];
+ slang_operation p[2];
int result;
- p2[0] = *params;
- if (!slang_operation_construct (p2 + 1))
+ p[0] = params[0];
+ if (!slang_operation_construct (&p[1]))
return 0;
- p2[1].type = slang_oper_literal_int;
- result = call_function_name (file, name, p2, 2, 0, space, info);
- slang_operation_destruct (p2 + 1);
+ p[1].type = slang_oper_literal_int;
+ result = call_function_name (file, name, p, 2, 0, space, info, mach, atoms);
+ slang_operation_destruct (&p[1]);
return result;
}
-static int call_asm_instruction (slang_assembly_file *file, const char *name)
+static const struct
{
- const struct
- {
- const char *name;
- slang_assembly_type code1, code2;
- } inst[] = {
- { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
- { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
- { "float_copy", slang_asm_float_copy, slang_asm_none },
- { "int_copy", slang_asm_int_copy, slang_asm_none },
- { "bool_copy", slang_asm_bool_copy, slang_asm_none },
- { "float_add", slang_asm_float_add, slang_asm_float_copy },
- { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
- { "float_divide", slang_asm_float_divide, slang_asm_float_copy },
- { "float_negate", slang_asm_float_negate, slang_asm_float_copy },
- { "float_less", slang_asm_float_less, slang_asm_bool_copy },
- { "float_equal", slang_asm_float_equal, slang_asm_bool_copy },
- { NULL, slang_asm_none, slang_asm_none }
- };
+ const char *name;
+ slang_assembly_type code1, code2;
+} inst[] = {
+ /* core */
+ { "float_add", slang_asm_float_add, slang_asm_float_copy },
+ { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy },
+ { "float_divide", slang_asm_float_divide, slang_asm_float_copy },
+ { "float_negate", slang_asm_float_negate, slang_asm_float_copy },
+ { "float_less", slang_asm_float_less, slang_asm_bool_copy },
+ { "float_equal", slang_asm_float_equal_exp,slang_asm_bool_copy },
+ { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy },
+ { "float_sine", slang_asm_float_sine, slang_asm_float_copy },
+ { "float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy },
+ { "float_arctan", slang_asm_float_arctan, slang_asm_float_copy },
+ { "float_power", slang_asm_float_power, slang_asm_float_copy },
+ { "float_log2", slang_asm_float_log2, slang_asm_float_copy },
+ { "float_floor", slang_asm_float_floor, slang_asm_float_copy },
+ { "float_ceil", slang_asm_float_ceil, slang_asm_float_copy },
+ { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy },
+ /* mesa-specific extensions */
+ { "float_print", slang_asm_float_deref, slang_asm_float_print },
+ { "int_print", slang_asm_int_deref, slang_asm_int_print },
+ { "bool_print", slang_asm_bool_deref, slang_asm_bool_print },
+ { NULL, slang_asm_none, slang_asm_none }
+};
+
+static int call_asm_instruction (slang_assembly_file *file, slang_atom a_name, slang_atom_pool *atoms)
+{
+ const char *id;
unsigned int i;
+ id = slang_atom_pool_id (atoms, a_name);
+
for (i = 0; inst[i].name != NULL; i++)
- if (slang_string_compare (name, inst[i].name) == 0)
+ if (slang_string_compare (id, inst[i].name) == 0)
break;
if (inst[i].name == NULL)
return 0;
- if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0))
+ if (!PLAB2 (file, inst[i].code1, 4, 0))
return 0;
if (inst[i].code2 != slang_asm_none)
- if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0))
+ if (!PLAB2 (file, inst[i].code2, 4, 0))
return 0;
/* clean-up the stack from the remaining dst address */
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+ if (!PLAB (file, slang_asm_local_free, 4))
return 0;
return 1;
}
-/* XXX: general swizzle! */
static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg,
unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label)
{
@@ -575,7 +685,7 @@ static int equality_aggregate (slang_assembly_file *file, const slang_storage_ag
for (i = 0; i < agg->count; i++)
{
- const slang_storage_array *arr = agg->arrays + i;
+ const slang_storage_array *arr = &agg->arrays[i];
unsigned int j;
for (j = 0; j < arr->length; j++)
@@ -587,39 +697,38 @@ static int equality_aggregate (slang_assembly_file *file, const slang_storage_ag
}
else
{
- if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index,
- *index))
+ if (!PLAB2 (file, slang_asm_float_equal_int, size + *index, *index))
return 0;
*index += 4;
- if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label))
+ if (!PLAB (file, slang_asm_jump_if_zero, z_label))
return 0;
}
}
}
return 1;
}
-/* XXX: general swizzle! */
+
static int equality (slang_assembly_file *file, slang_operation *op,
- slang_assembly_name_space *space, slang_assembly_local_info *info, int equal)
+ slang_assembly_name_space *space, slang_assembly_local_info *info, int equal,
+ slang_machine *mach, slang_atom_pool *atoms)
{
slang_assembly_typeinfo ti;
- int result;
+ int result = 0;
slang_storage_aggregate agg;
unsigned int index, size;
unsigned int skip_jump, true_label, true_jump, false_label, false_jump;
/* get type of operation */
- slang_assembly_typeinfo_construct (&ti);
- if (!_slang_typeof_operation (op, space, &ti))
- {
- slang_assembly_typeinfo_destruct (&ti);
+ if (!slang_assembly_typeinfo_construct (&ti))
return 0;
- }
+ if (!_slang_typeof_operation (op, space, &ti, atoms))
+ goto end1;
/* convert it to an aggregate */
- slang_storage_aggregate_construct (&agg);
- if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
- space->vars)))
+ if (!slang_storage_aggregate_construct (&agg))
+ goto end1;
+ if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs,
+ space->vars, mach, file, atoms))
goto end;
/* compute the size of the agregate - there are two such aggregates on the stack */
@@ -627,37 +736,35 @@ static int equality (slang_assembly_file *file, slang_operation *op,
/* jump to the actual data-comparison code */
skip_jump = file->count;
- if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
+ if (!PUSH (file, slang_asm_jump))
goto end;
/* pop off the stack the compared data and push 1 */
true_label = file->count;
- if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
+ if (!PLAB (file, slang_asm_local_free, size * 2))
goto end;
- if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)))
+ if (!PLIT (file, slang_asm_bool_push, (GLfloat) 1))
goto end;
true_jump = file->count;
- if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
+ if (!PUSH (file, slang_asm_jump))
goto end;
false_label = file->count;
- if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2)))
+ if (!PLAB (file, slang_asm_local_free, size * 2))
goto end;
- if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f)))
+ if (!PLIT (file, slang_asm_bool_push, (GLfloat) 0))
goto end;
false_jump = file->count;
- if (!(result = slang_assembly_file_push (file, slang_asm_jump)))
+ if (!PUSH (file, slang_asm_jump))
goto end;
file->code[skip_jump].param[0] = file->count;
/* compare the data on stack, it will eventually jump either to true or false label */
index = 0;
- if (!(result = equality_aggregate (file, &agg, &index, size, info,
- equal ? false_label : true_label)))
+ if (!equality_aggregate (file, &agg, &index, size, info, equal ? false_label : true_label))
goto end;
- if (!(result = slang_assembly_file_push_label (file, slang_asm_jump,
- equal ? true_label : false_label)))
+ if (!PLAB (file, slang_asm_jump, equal ? true_label : false_label))
goto end;
file->code[true_jump].param[0] = file->count;
@@ -666,20 +773,245 @@ static int equality (slang_assembly_file *file, slang_operation *op,
result = 1;
end:
slang_storage_aggregate_destruct (&agg);
+end1:
slang_assembly_typeinfo_destruct (&ti);
return result;
}
+static int handle_subscript (slang_assembly_typeinfo *tie, slang_assembly_typeinfo *tia,
+ slang_assembly_file *file, slang_operation *op, int reference, slang_assembly_flow_control *flow,
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_machine *mach,
+ slang_atom_pool *atoms)
+{
+ unsigned int asize = 0, esize = 0;
+ slang_assembly_stack_info _stk;
+
+ /* get type info of the master expression (matrix, vector or an array */
+ if (!_slang_typeof_operation (&op->children[0], space, tia, atoms))
+ return 0;
+ if (!sizeof_variable (&tia->spec, slang_qual_none, tia->array_size, space, &asize, mach, file,
+ atoms))
+ return 0;
+
+ /* get type info of the result (matrix column, vector row or array element) */
+ if (!_slang_typeof_operation (op, space, tie, atoms))
+ return 0;
+ if (!sizeof_variable (&tie->spec, slang_qual_none, NULL, space, &esize, mach, file, atoms))
+ return 0;
+
+ /* assemble the master expression */
+ if (!_slang_assemble_operation (file, &op->children[0], reference, flow, space, info, &_stk,
+ mach, atoms))
+ return 0;
+ /* ignre the _stk */
+
+ /* when indexing an l-value swizzle, push the swizzle_tmp */
+ if (reference && tia->is_swizzled)
+ {
+ if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
+ return 0;
+ }
+
+ /* assemble the subscript expression */
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &_stk, mach, atoms))
+ return 0;
+ /* ignore the _stk */
+
+ if (reference && tia->is_swizzled)
+ {
+ unsigned int i;
+
+ /* copy the swizzle indexes to the swizzle_tmp */
+ for (i = 0; i < tia->swz.num_components; i++)
+ {
+ if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
+ return 0;
+ if (!PLAB (file, slang_asm_addr_push, i * 4))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[i]))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_copy))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+ }
+
+ /* offset the pushed swizzle_tmp address and dereference it */
+ if (!PUSH (file, slang_asm_int_to_addr))
+ return 0;
+ if (!PLAB (file, slang_asm_addr_push, 4))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_multiply))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_deref))
+ return 0;
+ }
+ else
+ {
+ /* convert the integer subscript to a relative address */
+ if (!PUSH (file, slang_asm_int_to_addr))
+ return 0;
+ }
+
+ if (!PLAB (file, slang_asm_addr_push, esize))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_multiply))
+ return 0;
+
+ if (reference)
+ {
+ /* offset the base address with the relative address */
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ }
+ else
+ {
+ unsigned int i;
+
+ /* move the selected element to the beginning of the master expression */
+ for (i = 0; i < esize; i += 4)
+ if (!PLAB2 (file, slang_asm_float_move, asize - esize + i + 4, i + 4))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+
+ /* free the rest of the master expression */
+ if (!PLAB (file, slang_asm_local_free, asize - esize))
+ return 0;
+ }
+ return 1;
+}
+
+static int handle_field (slang_assembly_typeinfo *tia, slang_assembly_typeinfo *tib,
+ slang_assembly_file *file, slang_operation *op, int reference, slang_assembly_flow_control *flow,
+ slang_assembly_name_space *space, slang_assembly_local_info *info, slang_assembly_stack_info *stk,
+ slang_machine *mach, slang_atom_pool *atoms)
+{
+ slang_assembly_stack_info _stk;
+
+ /* get type info of the result (field or swizzle) */
+ if (!_slang_typeof_operation (op, space, tia, atoms))
+ return 0;
+
+ /* get type info of the master expression being accessed (struct or vector) */
+ if (!_slang_typeof_operation (&op->children[0], space, tib, atoms))
+ return 0;
+
+ /* if swizzling a vector in-place, the swizzle temporary is needed */
+ if (!reference && tia->is_swizzled)
+ if (!PLAB2 (file, slang_asm_local_addr, info->swizzle_tmp, 16))
+ return 0;
+
+ /* assemble the master expression */
+ if (!_slang_assemble_operation (file, &op->children[0], reference, flow, space, info, &_stk,
+ mach, atoms))
+ return 0;
+ /* ignore _stk.swizzle - we'll have it in tia->swz */
+
+ /* assemble the field expression */
+ if (tia->is_swizzled)
+ {
+ if (reference)
+ {
+ /*if (tia->swz.num_components == 1)
+ {
+ /* simple case - adjust the vector's address to point to the selected component */
+ /* if (!PLAB (file, slang_asm_addr_push, tia->swz.swizzle[0] * 4))
+ return 0;
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ }
+ else*/
+ {
+ /* two or more vector components are being referenced - the so-called write mask
+ * must be passed to the upper operations and applied when assigning value
+ * to this swizzle */
+ stk->swizzle = tia->swz;
+ }
+ }
+ else
+ {
+ /* swizzle the vector in-place using the swizzle temporary */
+ if (!_slang_assemble_constructor_from_swizzle (file, &tia->swz, &tia->spec, &tib->spec,
+ info))
+ return 0;
+ }
+ }
+ else
+ {
+ GLuint i, struct_size = 0, field_offset = 0, field_size = 0;
+
+ for (i = 0; i < tib->spec._struct->fields->num_variables; i++)
+ {
+ slang_variable *field;
+ slang_storage_aggregate agg;
+ GLuint size;
+
+ field = &tib->spec._struct->fields->variables[i];
+ if (!slang_storage_aggregate_construct (&agg))
+ return 0;
+ if (!_slang_aggregate_variable (&agg, &field->type.specifier, field->array_size,
+ space->funcs, space->structs, space->vars, mach, file, atoms))
+ {
+ slang_storage_aggregate_destruct (&agg);
+ return 0;
+ }
+ size = _slang_sizeof_aggregate (&agg);
+ slang_storage_aggregate_destruct (&agg);
+
+ if (op->a_id == field->a_name)
+ {
+ field_size = size;
+ struct_size = field_offset + size;
+ }
+ else if (struct_size != 0)
+ struct_size += size;
+ else
+ field_offset += size;
+ }
+
+ if (!PLAB (file, slang_asm_addr_push, field_offset))
+ return 0;
+
+ if (reference)
+ {
+ if (!PUSH (file, slang_asm_addr_add))
+ return 0;
+ }
+ else
+ {
+ unsigned int i;
+
+ /* move the selected element to the beginning of the master expression */
+ for (i = 0; i < field_size; i += 4)
+ if (!PLAB2 (file, slang_asm_float_move, struct_size - field_size + i + 4, i + 4))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+
+ /* free the rest of the master expression */
+ if (!PLAB (file, slang_asm_local_free, struct_size - field_size))
+ return 0;
+ }
+ }
+ return 1;
+}
+
int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference,
slang_assembly_flow_control *flow, slang_assembly_name_space *space,
- slang_assembly_local_info *info, slang_assembly_stack_info *stk)
+ slang_assembly_local_info *info, slang_assembly_stack_info *stk, slang_machine *mach,
+ slang_atom_pool *atoms)
{
unsigned int assem;
- stk->swizzle_mask = 0;
+ stk->swizzle.num_components = 0;
assem = file->count;
- if (!slang_assembly_file_push_new (file))
+ if (!push_new (file))
return 0;
switch (op->type)
@@ -688,13 +1020,16 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
case slang_oper_block_new_scope:
{
unsigned int i;
+
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[i], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children + i, 0, space))
+ /* ignore the stk */
+ if (!_slang_cleanup_stack (file, &op->children[i], 0, space, mach, atoms))
return 0;
}
}
@@ -713,15 +1048,17 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
case slang_oper_asm:
{
unsigned int i;
+
for (i = 0; i < op->num_children; i++)
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info,
- &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[i], i == 0, flow, space, info,
+ &stk, mach, atoms))
return 0;
- /* TODO: inspect stk */
+ /* __asm statement does not support any swizzles, so lets ignore stk for now */
}
- if (!call_asm_instruction (file, op->identifier))
+ if (!call_asm_instruction (file, op->a_id, atoms))
return 0;
}
break;
@@ -735,48 +1072,57 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
break;
case slang_oper_discard:
file->code[assem].type = slang_asm_discard;
- if (!slang_assembly_file_push (file, slang_asm_exit))
+ if (!PUSH (file, slang_asm_exit))
return 0;
break;
case slang_oper_return:
if (info->ret_size != 0)
{
slang_assembly_stack_info stk;
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size))
+
+ /* push the result's address */
+ if (!PLAB2 (file, slang_asm_local_addr, 0, info->ret_size))
return 0;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!_slang_assemble_assignment (file, op->children, space, info))
+
+ /* ignore the stk from latest operation, reset swizzle to 0 for the assignment */
+ stk.swizzle.num_components = 0;
+ /* assign the operation to the function result (it was reserved on the stack) */
+ if (!_slang_assemble_assignment (file, op->children, space, info, &stk, mach, atoms))
return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
+
+ if (!PLAB (file, slang_asm_local_free, 4))
return 0;
}
- if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end))
+ if (!PLAB (file, slang_asm_jump, flow->function_end))
return 0;
break;
case slang_oper_expression:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk))
+
+ assert (!reference);
+ if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk, mach, atoms))
return 0;
- /* TODO: inspect stk */
+ /* ignore the stk info */
}
break;
case slang_oper_if:
- if (!_slang_assemble_if (file, op, flow, space, info))
+ if (!_slang_assemble_if (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_while:
- if (!_slang_assemble_while (file, op, flow, space, info))
+ if (!_slang_assemble_while (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_do:
- if (!_slang_assemble_do (file, op, flow, space, info))
+ if (!_slang_assemble_do (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_for:
- if (!_slang_assemble_for (file, op, flow, space, info))
+ if (!_slang_assemble_for (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_void:
@@ -797,69 +1143,75 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
{
slang_variable *var;
unsigned int size;
- var = _slang_locate_variable (op->locals, op->identifier, 1);
+
+ /* find the variable and calculate its size */
+ var = _slang_locate_variable (op->locals, op->a_id, 1);
if (var == NULL)
return 0;
size = 0;
if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space,
- &size))
+ &size, mach, file, atoms))
return 0;
- if (var->initializer != NULL)
+
+ /* prepare stack for dereferencing */
+ if (!reference)
+ if (!PLAB2 (file, slang_asm_local_addr, info->addr_tmp, 4))
+ return 0;
+
+ /* push the variable's address */
+ if (var->global)
{
- assert (!"var->initializer, oper_identifier");
+ if (!PLAB (file, slang_asm_addr_push, var->address))
+ return 0;
}
else
{
- if (!reference)
- {
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
- info->addr_tmp, 4))
- return 0;
- }
- /* XXX: globals! */
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address,
- size))
+ if (!PLAB2 (file, slang_asm_local_addr, var->address, size))
+ return 0;
+ }
+
+ /* perform the dereference */
+ if (!reference)
+ {
+ if (!PUSH (file, slang_asm_addr_copy))
+ return 0;
+ if (!PLAB (file, slang_asm_local_free, 4))
+ return 0;
+ if (!_slang_dereference (file, op, space, info, mach, atoms))
return 0;
- if (!reference)
- {
- if (!slang_assembly_file_push (file, slang_asm_addr_copy))
- return 0;
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
- return 0;
- if (!dereference (file, op, space, info))
- return 0;
- }
}
}
break;
case slang_oper_sequence:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
/* TODO: pass-in stk to cleanup */
- if (!_slang_cleanup_stack (file, op->children, 0, space))
+ if (!_slang_cleanup_stack (file, &op->children[0], 0, space, mach, atoms))
return 0;
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info,
- &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info,
+ &stk, mach, atoms))
return 0;
/* TODO: inspect stk */
}
break;
case slang_oper_assign:
- if (!_slang_assemble_assign (file, op, "=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_addassign:
- if (!_slang_assemble_assign (file, op, "+=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "+=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_subassign:
- if (!_slang_assemble_assign (file, op, "-=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "-=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_mulassign:
- if (!_slang_assemble_assign (file, op, "*=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "*=", reference, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_modassign:*/
@@ -869,214 +1221,149 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
/*case slang_oper_xorassign:*/
/*case slang_oper_andassign:*/
case slang_oper_divassign:
- if (!_slang_assemble_assign (file, op, "/=", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "/=", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_select:
- if (!_slang_assemble_select (file, op, flow, space, info))
+ if (!_slang_assemble_select (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_logicalor:
- if (!_slang_assemble_logicalor (file, op, flow, space, info))
+ if (!_slang_assemble_logicalor (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_logicaland:
- if (!_slang_assemble_logicaland (file, op, flow, space, info))
+ if (!_slang_assemble_logicaland (file, op, flow, space, info, mach, atoms))
return 0;
break;
case slang_oper_logicalxor:
- if (!call_function_name (file, "^^", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "^^", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_bitor:*/
/*case slang_oper_bitxor:*/
/*case slang_oper_bitand:*/
case slang_oper_less:
- if (!call_function_name (file, "<", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "<", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_greater:
- if (!call_function_name (file, ">", op->children, 2, 0, space, info))
+ if (!call_function_name (file, ">", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_lessequal:
- if (!call_function_name (file, "<=", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "<=", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_greaterequal:
- if (!call_function_name (file, ">=", op->children, 2, 0, space, info))
+ if (!call_function_name (file, ">=", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_lshift:*/
/*case slang_oper_rshift:*/
case slang_oper_add:
- if (!call_function_name (file, "+", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "+", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_subtract:
- if (!call_function_name (file, "-", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "-", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_multiply:
- if (!call_function_name (file, "*", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "*", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_modulus:*/
case slang_oper_divide:
- if (!call_function_name (file, "/", op->children, 2, 0, space, info))
+ if (!call_function_name (file, "/", op->children, 2, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_equal:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!equality (file, op->children, space, info, 1))
+ if (!equality (file, op->children, space, info, 1, mach, atoms))
return 0;
}
break;
case slang_oper_notequal:
{
slang_assembly_stack_info stk;
- if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk))
+
+ if (!_slang_assemble_operation (file, &op->children[0], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk))
+ if (!_slang_assemble_operation (file, &op->children[1], 0, flow, space, info, &stk,
+ mach, atoms))
return 0;
- /* TODO: inspect stk */
- if (!equality (file, op->children, space, info, 0))
+ if (!equality (file, op->children, space, info, 0, mach, atoms))
return 0;
}
break;
case slang_oper_preincrement:
- if (!_slang_assemble_assign (file, op, "++", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "++", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_predecrement:
- if (!_slang_assemble_assign (file, op, "--", reference, space, info))
+ if (!_slang_assemble_assign (file, op, "--", reference, space, info, mach, atoms))
return 0;
break;
case slang_oper_plus:
- if (!call_function_name (file, "+", op->children, 1, 0, space, info))
+ if (!_slang_dereference (file, op, space, info, mach, atoms))
return 0;
break;
case slang_oper_minus:
- if (!call_function_name (file, "-", op->children, 1, 0, space, info))
+ if (!call_function_name (file, "-", op->children, 1, 0, space, info, mach, atoms))
return 0;
break;
/*case slang_oper_complement:*/
case slang_oper_not:
- if (!call_function_name (file, "!", op->children, 1, 0, space, info))
+ if (!call_function_name (file, "!", op->children, 1, 0, space, info, mach, atoms))
return 0;
break;
case slang_oper_subscript:
{
- slang_assembly_stack_info _stk;
slang_assembly_typeinfo ti_arr, ti_elem;
- unsigned int arr_size = 0, elem_size = 0;
- if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
- &_stk))
- return 0;
- if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk))
- return 0;
- slang_assembly_typeinfo_construct (&ti_arr);
- if (!_slang_typeof_operation (op->children, space, &ti_arr))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- return 0;
- }
- if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- return 0;
- }
- slang_assembly_typeinfo_construct (&ti_elem);
- if (!_slang_typeof_operation (op, space, &ti_elem))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- if (!slang_assembly_file_push (file, slang_asm_int_to_addr))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
+
+ if (!slang_assembly_typeinfo_construct (&ti_arr))
return 0;
- }
- if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size))
+ if (!slang_assembly_typeinfo_construct (&ti_elem))
{
slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
- if (!slang_assembly_file_push (file, slang_asm_addr_multiply))
+ if (!handle_subscript (&ti_elem, &ti_arr, file, op, reference, flow, space, info,
+ mach, atoms))
{
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
return 0;
}
- if (reference)
- {
- if (!slang_assembly_file_push (file, slang_asm_addr_add))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- }
- else
- {
- unsigned int i;
- for (i = 0; i < elem_size; i += 4)
- {
- if (!slang_assembly_file_push_label2 (file, slang_asm_float_move,
- arr_size - elem_size + i + 4, i + 4))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- }
- if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- if (!slang_assembly_file_push_label (file, slang_asm_local_free,
- arr_size - elem_size))
- {
- slang_assembly_typeinfo_destruct (&ti_arr);
- slang_assembly_typeinfo_destruct (&ti_elem);
- return 0;
- }
- }
slang_assembly_typeinfo_destruct (&ti_arr);
slang_assembly_typeinfo_destruct (&ti_elem);
}
break;
case slang_oper_call:
{
- slang_function *fun = _slang_locate_function (op->identifier, op->children,
- op->num_children, space);
+ slang_function *fun;
+
+ fun = _slang_locate_function (space->funcs, op->a_id, op->children, op->num_children,
+ space, atoms);
if (fun == NULL)
{
- if (!_slang_assemble_constructor (file, op, flow, space, info))
- return 0;
+/* if (!_slang_assemble_constructor (file, op, flow, space, info, mach))
+*/ return 0;
}
else
{
- if (!call_function (file, fun, op->children, op->num_children, 0, space, info))
+ if (!_slang_call_function (file, fun, op->children, op->num_children, 0, space,
+ info, mach, atoms))
return 0;
}
}
@@ -1084,101 +1371,31 @@ int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, i
case slang_oper_field:
{
slang_assembly_typeinfo ti_after, ti_before;
- slang_assembly_stack_info _stk;
- slang_assembly_typeinfo_construct (&ti_after);
- if (!_slang_typeof_operation (op, space, &ti_after))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
+
+ if (!slang_assembly_typeinfo_construct (&ti_after))
return 0;
- }
- slang_assembly_typeinfo_construct (&ti_before);
- if (!_slang_typeof_operation (op->children, space, &ti_before))
+ if (!slang_assembly_typeinfo_construct (&ti_before))
{
slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
- if (!reference && ti_after.is_swizzled)
- {
- if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr,
- info->swizzle_tmp, 16))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- }
- if (!_slang_assemble_operation (file, op->children, reference, flow, space, info,
- &_stk))
+ if (!handle_field (&ti_after, &ti_before, file, op, reference, flow, space, info, stk,
+ mach, atoms))
{
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
return 0;
}
- /* TODO: inspect stk */
- if (ti_after.is_swizzled)
- {
- if (reference)
- {
- if (ti_after.swz.num_components == 1)
- {
- if (!slang_assembly_file_push_label (file, slang_asm_addr_push,
- ti_after.swz.swizzle[0] * 4))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- if (!slang_assembly_file_push (file, slang_asm_addr_add))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- }
- else
- {
- unsigned int i;
- for (i = 0; i < ti_after.swz.num_components; i++)
- stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i];
- }
- }
- else
- {
- if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz,
- &ti_after.spec, &ti_before.spec, info))
- {
- slang_assembly_typeinfo_destruct (&ti_after);
- slang_assembly_typeinfo_destruct (&ti_before);
- return 0;
- }
- }
- }
- else
- {
- if (reference)
- {
- /* TODO: struct field address */
- }
- else
- {
- /* TODO: struct field value */
- }
- }
slang_assembly_typeinfo_destruct (&ti_after);
slang_assembly_typeinfo_destruct (&ti_before);
}
break;
case slang_oper_postincrement:
- if (!call_function_name_dummyint (file, "++", op->children, space, info))
- return 0;
- if (!dereference (file, op, space, info))
+ if (!call_function_name_dummyint (file, "++", op->children, space, info, mach, atoms))
return 0;
break;
case slang_oper_postdecrement:
- if (!call_function_name_dummyint (file, "--", op->children, space, info))
- return 0;
- if (!dereference (file, op, space, info))
+ if (!call_function_name_dummyint (file, "--", op->children, space, info, mach, atoms))
return 0;
break;
default: