diff options
-rw-r--r-- | src/mesa/shader/slang/slang_execute.c | 808 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_execute.h | 105 | ||||
-rw-r--r-- | src/mesa/shader/slang/slang_execute_x86.c | 756 |
3 files changed, 0 insertions, 1669 deletions
diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c deleted file mode 100644 index 1561df19450..00000000000 --- a/src/mesa/shader/slang/slang_execute.c +++ /dev/null @@ -1,808 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file slang_execute.c - * intermediate code interpreter - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_compile.h" -#include "slang_execute.h" -#include "slang_library_noise.h" -#include "slang_library_texsample.h" - -#define DEBUG_SLANG 0 - -GLvoid -slang_machine_ctr(slang_machine * self) -{ - slang_machine_init(self); - self->infolog = NULL; -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ - self->x86.compiled_func = NULL; -#endif -} - -GLvoid -slang_machine_dtr(slang_machine * self) -{ - if (self->infolog != NULL) { - slang_info_log_destruct(self->infolog); - slang_alloc_free(self->infolog); - } -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ - if (self->x86.compiled_func != NULL) - _mesa_exec_free(self->x86.compiled_func); -#endif -} - - -/** - * Initialize the shader virtual machine. - * NOTE: stack grows downward in memory. - */ -void -slang_machine_init(slang_machine * mach) -{ - mach->ip = 0; - mach->sp = SLANG_MACHINE_STACK_SIZE; - mach->bp = 0; - mach->kill = GL_FALSE; - mach->exit = GL_FALSE; -} - -#if DEBUG_SLANG - -static void -dump_instruction(FILE * f, slang_assembly * a, unsigned int i) -{ - fprintf(f, "%.5u:\t", i); - - switch (a->type) { - /* core */ - case slang_asm_none: - fprintf(f, "none"); - break; - case slang_asm_float_copy: - fprintf(f, "float_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_move: - fprintf(f, "float_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_push: - fprintf(f, "float_push\t%f", a->literal); - break; - case slang_asm_float_deref: - fprintf(f, "float_deref"); - break; - case slang_asm_float_add: - fprintf(f, "float_add"); - break; - case slang_asm_float_multiply: - fprintf(f, "float_multiply"); - break; - case slang_asm_float_divide: - fprintf(f, "float_divide"); - break; - case slang_asm_float_negate: - fprintf(f, "float_negate"); - break; - case slang_asm_float_less: - fprintf(f, "float_less"); - break; - case slang_asm_float_equal_exp: - fprintf(f, "float_equal"); - break; - case slang_asm_float_equal_int: - fprintf(f, "float_equal\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_to_int: - fprintf(f, "float_to_int"); - break; - case slang_asm_float_sine: - fprintf(f, "float_sine"); - break; - case slang_asm_float_arcsine: - fprintf(f, "float_arcsine"); - break; - case slang_asm_float_arctan: - fprintf(f, "float_arctan"); - break; - case slang_asm_float_power: - fprintf(f, "float_power"); - break; - case slang_asm_float_log2: - fprintf(f, "float_log2"); - break; - case slang_asm_float_floor: - fprintf(f, "float_floor"); - break; - case slang_asm_float_ceil: - fprintf(f, "float_ceil"); - break; - case slang_asm_float_noise1: - fprintf(f, "float_noise1"); - break; - case slang_asm_float_noise2: - fprintf(f, "float_noise2"); - break; - case slang_asm_float_noise3: - fprintf(f, "float_noise3"); - break; - case slang_asm_float_noise4: - fprintf(f, "float_noise4"); - break; - case slang_asm_int_copy: - fprintf(f, "int_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_int_move: - fprintf(f, "int_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_int_push: - fprintf(f, "int_push\t%d", (GLint) a->literal); - break; - case slang_asm_int_deref: - fprintf(f, "int_deref"); - break; - case slang_asm_int_to_float: - fprintf(f, "int_to_float"); - break; - case slang_asm_int_to_addr: - fprintf(f, "int_to_addr"); - break; - case slang_asm_bool_copy: - fprintf(f, "bool_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_bool_move: - fprintf(f, "bool_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_bool_push: - fprintf(f, "bool_push\t%d", a->literal != 0.0f); - break; - case slang_asm_bool_deref: - fprintf(f, "bool_deref"); - break; - case slang_asm_addr_copy: - fprintf(f, "addr_copy"); - break; - case slang_asm_addr_push: - fprintf(f, "addr_push\t%u", a->param[0]); - break; - case slang_asm_addr_deref: - fprintf(f, "addr_deref"); - break; - case slang_asm_addr_add: - fprintf(f, "addr_add"); - break; - case slang_asm_addr_multiply: - fprintf(f, "addr_multiply"); - break; - case slang_asm_vec4_tex1d: - fprintf(f, "vec4_tex1d"); - break; - case slang_asm_vec4_tex2d: - fprintf(f, "vec4_tex2d"); - break; - case slang_asm_vec4_tex3d: - fprintf(f, "vec4_tex3d"); - break; - case slang_asm_vec4_texcube: - fprintf(f, "vec4_texcube"); - break; - case slang_asm_vec4_shad1d: - fprintf(f, "vec4_shad1d"); - break; - case slang_asm_vec4_shad2d: - fprintf(f, "vec4_shad2d"); - break; - case slang_asm_jump: - fprintf(f, "jump\t%u", a->param[0]); - break; - case slang_asm_jump_if_zero: - fprintf(f, "jump_if_zero\t%u", a->param[0]); - break; - case slang_asm_enter: - fprintf(f, "enter\t%u", a->param[0]); - break; - case slang_asm_leave: - fprintf(f, "leave"); - break; - case slang_asm_local_alloc: - fprintf(f, "local_alloc\t%u", a->param[0]); - break; - case slang_asm_local_free: - fprintf(f, "local_free\t%u", a->param[0]); - break; - case slang_asm_local_addr: - fprintf(f, "local_addr\t%u, %u", a->param[0], a->param[1]); - break; - case slang_asm_global_addr: - fprintf(f, "global_addr\t%u", a->param[0]); - break; - case slang_asm_call: - fprintf(f, "call\t%u", a->param[0]); - break; - case slang_asm_return: - fprintf(f, "return"); - break; - case slang_asm_discard: - fprintf(f, "discard"); - break; - case slang_asm_exit: - fprintf(f, "exit"); - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - fprintf(f, "float_print"); - break; - case slang_asm_int_print: - fprintf(f, "int_print"); - break; - case slang_asm_bool_print: - fprintf(f, "bool_print"); - break; - /* vec4 */ - case slang_asm_float_to_vec4: - fprintf(f, "float_to_vec4"); - break; - case slang_asm_vec4_add: - fprintf(f, "vec4_add"); - break; - case slang_asm_vec4_subtract: - fprintf(f, "vec4_subtract"); - break; - case slang_asm_vec4_multiply: - fprintf(f, "vec4_multiply"); - break; - case slang_asm_vec4_divide: - fprintf(f, "vec4_divide"); - break; - case slang_asm_vec4_negate: - fprintf(f, "vec4_negate"); - break; - case slang_asm_vec4_dot: - fprintf(f, "vec4_dot"); - break; - case slang_asm_vec4_copy: - fprintf(f, "vec4_copy"); - break; - case slang_asm_vec4_deref: - fprintf(f, "vec4_deref"); - break; - case slang_asm_vec4_equal_int: - fprintf(f, "vec4_equal"); - break; - default: - break; - } - - fprintf(f, "\n"); -} - -static void -dump(const slang_assembly_file * file) -{ - unsigned int i; - static unsigned int counter = 0; - FILE *f; - char filename[256]; - - counter++; - _mesa_sprintf(filename, "~mesa-slang-assembly-dump-(%u).txt", counter); - f = fopen(filename, "w"); - if (f == NULL) - return; - - for (i = 0; i < file->count; i++) - dump_instruction(f, file->code + i, i); - - fclose(f); -} - -#endif - -static GLvoid -ensure_infolog_created(slang_info_log ** infolog) -{ - if (*infolog == NULL) { - *infolog = slang_alloc_malloc(sizeof(slang_info_log)); - if (*infolog == NULL) - return; - slang_info_log_construct(*infolog); - } -} - -GLboolean -_slang_execute2(const slang_assembly_file * file, slang_machine * mach) -{ - slang_machine_slot *stack; - -#if DEBUG_SLANG - static unsigned int counter = 0; - char filename[256]; - FILE *f; -#endif - - /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */ - static_assert(sizeof(GLfloat) == 4); - static_assert(sizeof(GLuint) == 4); - -#if DEBUG_SLANG - dump(file); - counter++; - _mesa_sprintf(filename, "~mesa-slang-assembly-exec-(%u).txt", counter); - f = fopen(filename, "w"); -#endif - -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ - if (mach->x86.compiled_func != NULL) { - mach->x86.compiled_func(mach); - return GL_TRUE; - } -#endif - - stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE; - - while (!mach->exit) { - const slang_assembly *a = &file->code[mach->ip]; - -#if DEBUG_SLANG - if (f != NULL && a->type != slang_asm_none) { - unsigned int i; - - dump_instruction(f, file->code + mach->ip, mach->ip); - fprintf(f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp); - for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++) - fprintf(f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, - stack[i]._addr); - fflush(f); - } -#endif - - mach->ip++; - - switch (a->type) { - /* core */ - case slang_asm_none: - break; - case slang_asm_float_copy: - case slang_asm_int_copy: - case slang_asm_bool_copy: - /* store top value on stack to memory */ -#if 0 - { - GLuint address - = (stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4; - GLfloat value = stack[mach->sp]._float; - mach->mem[address]._float = value; - } -#else - mach->mem[(stack[mach->sp + a->param[0] / 4]._addr +a->param[1]) / 4]._float = stack[mach->sp]._float; -#endif - mach->sp++; - break; - case slang_asm_float_move: - case slang_asm_int_move: - case slang_asm_bool_move: - stack[mach->sp + a->param[0] / 4]._float = - stack[mach->sp + - (stack[mach->sp]._addr + a->param[1]) / 4]._float; - break; - case slang_asm_float_push: - case slang_asm_int_push: - case slang_asm_bool_push: - /* push float/int/bool literal onto stop of stack */ - mach->sp--; - stack[mach->sp]._float = a->literal; - break; - case slang_asm_float_deref: - case slang_asm_int_deref: - case slang_asm_bool_deref: - /* load value from memory, replace stop of stack with it */ - stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float; - break; - case slang_asm_float_add: - /* pop two top floats, push sum */ - stack[mach->sp + 1]._float += stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_subtract: - stack[mach->sp + 1]._float -= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_multiply: - stack[mach->sp + 1]._float *= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_divide: - stack[mach->sp + 1]._float /= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_negate: - stack[mach->sp]._float = -stack[mach->sp]._float; - break; - case slang_asm_float_less: - stack[mach->sp + 1]._float = - (stack[mach->sp + 1]._float < stack[mach->sp]._float) - ? (GLfloat) 1 : (GLfloat) 0; - mach->sp++; - break; - case slang_asm_float_equal_exp: - stack[mach->sp + 1]._float = - (stack[mach->sp + 1]._float == stack[mach->sp]._float) - ? (GLfloat) 1 : (GLfloat) 0; - mach->sp++; - break; - case slang_asm_float_equal_int: - /* pop top two values, compare, push 0 or 1 */ - mach->sp--; - stack[mach->sp]._float = - (stack[mach->sp + 1 + a->param[0] / 4]._float == - stack[mach->sp + 1 + a->param[1] / 4]._float) - ? (GLfloat) 1 : (GLfloat) 0; - break; - case slang_asm_float_to_int: - stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float; - break; - case slang_asm_float_sine: - stack[mach->sp]._float = (GLfloat) _mesa_sin(stack[mach->sp]._float); - break; - case slang_asm_float_arcsine: - stack[mach->sp]._float = _mesa_asinf(stack[mach->sp]._float); - break; - case slang_asm_float_arctan: - stack[mach->sp]._float = _mesa_atanf(stack[mach->sp]._float); - break; - case slang_asm_float_power: - stack[mach->sp + 1]._float = (GLfloat) - _mesa_pow(stack[mach->sp + 1]._float, stack[mach->sp]._float); - mach->sp++; - break; - case slang_asm_float_log2: - stack[mach->sp]._float = LOG2(stack[mach->sp]._float); - break; -#if 0 - case slang_asm_float_floor: - stack[mach->sp]._float = FLOORF(stack[mach->sp]._float); - break; - case slang_asm_float_ceil: - stack[mach->sp]._float = CEILF(stack[mach->sp]._float); - break; -#endif - case slang_asm_float_noise1: - stack[mach->sp]._float = - _slang_library_noise1(stack[mach->sp]._float); - break; - case slang_asm_float_noise2: - stack[mach->sp + 1]._float = - _slang_library_noise2(stack[mach->sp]._float, - stack[mach->sp + 1]._float); - mach->sp++; - break; - case slang_asm_float_noise3: - stack[mach->sp + 2]._float = - _slang_library_noise3(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float); - mach->sp += 2; - break; - case slang_asm_float_noise4: - stack[mach->sp + 3]._float = - _slang_library_noise4(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float); - mach->sp += 3; - break; - case slang_asm_int_to_float: - break; - case slang_asm_int_to_addr: - stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float; - break; - case slang_asm_addr_copy: - mach->mem[stack[mach->sp + 1]._addr / 4]._addr = - stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_addr_push: - case slang_asm_global_addr: - mach->sp--; - stack[mach->sp]._addr = a->param[0]; - break; - case slang_asm_addr_deref: - stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr; - break; - case slang_asm_addr_add: - stack[mach->sp + 1]._addr += stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_addr_multiply: - stack[mach->sp + 1]._addr *= stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_vec4_tex1d: - _slang_library_tex1d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - &mach->mem[stack[mach->sp + 3]._addr / - 4]._float); - mach->sp += 3; - break; - case slang_asm_vec4_tex2d: - _slang_library_tex2d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - &mach->mem[stack[mach->sp + 4]._addr / - 4]._float); - mach->sp += 4; - break; - case slang_asm_vec4_tex3d: - _slang_library_tex3d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_texcube: - _slang_library_texcube(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_shad1d: - _slang_library_shad1d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_shad2d: - _slang_library_shad2d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_jump: - mach->ip = a->param[0]; - break; - case slang_asm_jump_if_zero: - if (stack[mach->sp]._float == 0.0f) - mach->ip = a->param[0]; - mach->sp++; - break; - case slang_asm_enter: - mach->sp--; - stack[mach->sp]._addr = mach->bp; - mach->bp = mach->sp + a->param[0] / 4; - break; - case slang_asm_leave: - mach->bp = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_local_alloc: - mach->sp -= a->param[0] / 4; - break; - case slang_asm_local_free: - mach->sp += a->param[0] / 4; - break; - case slang_asm_local_addr: - mach->sp--; - stack[mach->sp]._addr = - SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - (a->param[0] + - a->param[1]) + 4; - break; - case slang_asm_call: - mach->sp--; - stack[mach->sp]._addr = mach->ip; - mach->ip = a->param[0]; - break; - case slang_asm_return: - mach->ip = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_discard: - mach->kill = GL_TRUE; - break; - case slang_asm_exit: - mach->exit = GL_TRUE; - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - _mesa_printf("slang print: %f\n", stack[mach->sp]._float); - ensure_infolog_created(&mach->infolog); - slang_info_log_print(mach->infolog, "%f", stack[mach->sp]._float); - break; - case slang_asm_int_print: - _mesa_printf("slang print: %d\n", (GLint) stack[mach->sp]._float); - ensure_infolog_created(&mach->infolog); - slang_info_log_print(mach->infolog, "%d", - (GLint) (stack[mach->sp]._float)); - break; - case slang_asm_bool_print: - _mesa_printf("slang print: %s\n", - (GLint) stack[mach->sp]._float ? "true" : "false"); - ensure_infolog_created(&mach->infolog); - slang_info_log_print(mach->infolog, "%s", - (GLint) (stack[mach->sp]. - _float) ? "true" : "false"); - break; - /* vec4 */ - case slang_asm_float_to_vec4: - /* [vec4] | float > [vec4] */ - { - GLuint da = stack[mach->sp + 1]._addr; - mach->mem[da / 4]._float = stack[mach->sp]._float; - mach->sp++; - } - break; - case slang_asm_vec4_add: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float += stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float += stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float += stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float += stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_subtract: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float -= stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float -= stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float -= stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float -= stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_multiply: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float *= stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float *= stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float *= stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float *= stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_divide: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float /= stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float /= stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float /= stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float /= stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_negate: - /* [vec4] > [vec4] */ - { - GLuint da = stack[mach->sp]._addr; - mach->mem[da / 4]._float = -mach->mem[da / 4]._float; - mach->mem[(da + 4) / 4]._float = -mach->mem[(da + 4) / 4]._float; - mach->mem[(da + 8) / 4]._float = -mach->mem[(da + 8) / 4]._float; - mach->mem[(da + 12) / 4]._float = - -mach->mem[(da + 12) / 4]._float; - } - break; -#if 0 - case slang_asm_vec4_dot: - /* [vec4] | vec4 > [float] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float = - mach->mem[da / 4]._float * stack[mach->sp]._float + - mach->mem[(da + 4) / 4]._float * stack[mach->sp + 1]._float + - mach->mem[(da + 8) / 4]._float * stack[mach->sp + 2]._float + - mach->mem[(da + 12) / 4]._float * stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; -#endif - case slang_asm_vec4_copy: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + a->param[0] / 4]._addr + a->param[1]; - mach->mem[da / 4]._float = stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float = stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float = stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float = stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_deref: - /* [vec4] > vec4 */ - { - GLuint sa = stack[mach->sp]._addr; - mach->sp -= 3; - stack[mach->sp]._float = mach->mem[sa / 4]._float; - stack[mach->sp + 1]._float = mach->mem[(sa + 4) / 4]._float; - stack[mach->sp + 2]._float = mach->mem[(sa + 8) / 4]._float; - stack[mach->sp + 3]._float = mach->mem[(sa + 12) / 4]._float; - } - break; - case slang_asm_vec4_equal_int: - { - GLuint sp0 = mach->sp + a->param[0] / 4; - GLuint sp1 = mach->sp + a->param[1] / 4; - mach->sp--; - if (stack[sp0]._float == stack[sp1]._float && - stack[sp0 + 1]._float == stack[sp1 + 1]._float && - stack[sp0 + 2]._float == stack[sp1 + 2]._float && - stack[sp0 + 3]._float == stack[sp1 + 3]._float) { - stack[mach->sp]._float = 1.0f; - } - else { - stack[mach->sp]._float = 0.0f; - } - } - break; - case slang_asm_vec4_dot: - case slang_asm_vec3_dot: - { - /* XXX almost certainly wrong */ - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float = - mach->mem[da / 4]._float * stack[mach->sp]._float + - mach->mem[(da + 4) / 4]._float * stack[mach->sp + 1]._float + - mach->mem[(da + 8) / 4]._float * stack[mach->sp + 2]._float + - mach->mem[(da + 12) / 4]._float * stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - default: - _mesa_problem(NULL, "bad slang opcode 0x%x", a->type); - return GL_FALSE; - } - } - -#if DEBUG_SLANG - if (f != NULL) - fclose(f); -#endif - - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_execute.h b/src/mesa/shader/slang/slang_execute.h deleted file mode 100644 index 1f8c3781a1d..00000000000 --- a/src/mesa/shader/slang/slang_execute.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef SLANG_EXECUTE_H -#define SLANG_EXECUTE_H - -#include "slang_assemble.h" - -#if defined __cplusplus -extern "C" { -#endif - - -/** - * A memory location - */ -typedef union slang_machine_slot_ -{ - GLfloat _float; - GLuint _addr; -} slang_machine_slot; - -#define SLANG_MACHINE_GLOBAL_SIZE 3072 -#define SLANG_MACHINE_STACK_SIZE 1024 -#define SLANG_MACHINE_MEMORY_SIZE (SLANG_MACHINE_GLOBAL_SIZE + SLANG_MACHINE_STACK_SIZE) - - -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ -/** - * Extra machine state for x86 execution. - */ -typedef struct -{ - GLvoid(*compiled_func) (struct slang_machine_ *); - GLuint esp_restore; - GLshort fpucntl_rnd_neg; - GLshort fpucntl_restore; -} slang_machine_x86; -#endif - - -/** - * Runtime shader machine state. - */ -typedef struct slang_machine_ -{ - GLuint ip; /**< instruction pointer, for flow control */ - GLuint sp; /**< stack pointer, for stack access */ - GLuint bp; /**< base pointer, for local variable access */ - GLboolean kill; /**< discard the fragment? */ - GLboolean exit; /**< terminate the shader */ - /** Machine memory */ - slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE]; - struct slang_info_log_ *infolog; /**< printMESA() support */ -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ - slang_machine_x86 x86; -#endif -} slang_machine; - - -extern GLvoid -slang_machine_ctr(slang_machine *); - -extern GLvoid -slang_machine_dtr(slang_machine *); - -extern void -slang_machine_init(slang_machine *); - -extern GLboolean -_slang_execute2(const slang_assembly_file *, slang_machine *); - - -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ -extern GLboolean -_slang_x86_codegen(slang_machine *, slang_assembly_file *, GLuint); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/mesa/shader/slang/slang_execute_x86.c b/src/mesa/shader/slang/slang_execute_x86.c deleted file mode 100644 index c48c9667c79..00000000000 --- a/src/mesa/shader/slang/slang_execute_x86.c +++ /dev/null @@ -1,756 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file slang_execute_x86.c - * x86 back end compiler - * \author Michal Krol, Keith Whitwell - */ - -#include "imports.h" -#include "slang_compile.h" -#include "slang_execute.h" -#include "slang_library_noise.h" -#include "slang_library_texsample.h" - -#if 0/*defined(USE_X86_ASM) || defined(SLANG_X86)*/ - -#include "x86/rtasm/x86sse.h" - -typedef struct -{ - GLuint index; - GLubyte *csr; -} fixup; - -typedef struct -{ - struct x86_function f; - struct x86_reg r_eax; - struct x86_reg r_ecx; - struct x86_reg r_edx; - struct x86_reg r_ebx; - struct x86_reg r_esp; - struct x86_reg r_ebp; - struct x86_reg r_st0; - struct x86_reg r_st1; - struct x86_reg r_st2; - struct x86_reg r_st3; - struct x86_reg r_st4; - fixup *fixups; - GLuint fixup_count; - GLubyte **labels; - slang_machine *mach; - GLubyte *l_discard; - GLubyte *l_exit; - GLshort fpucntl; -} codegen_ctx; - -static GLvoid -add_fixup(codegen_ctx * G, GLuint index, GLubyte * csr) -{ - G->fixups = - (fixup *) slang_alloc_realloc(G->fixups, G->fixup_count * sizeof(fixup), - (G->fixup_count + 1) * sizeof(fixup)); - G->fixups[G->fixup_count].index = index; - G->fixups[G->fixup_count].csr = csr; - G->fixup_count++; -} - -#ifdef NO_FAST_MATH -#define RESTORE_FPU (DEFAULT_X86_FPU) -#define RND_NEG_FPU (DEFAULT_X86_FPU | 0x400) -#else -#define RESTORE_FPU (FAST_X86_FPU) -#define RND_NEG_FPU (FAST_X86_FPU | 0x400) -#endif - -#if 0 - -/* - * XXX - * These should produce a valid code that computes powers. - * Unfortunately, it does not. - */ -static void -set_fpu_round_neg_inf(codegen_ctx * G) -{ - if (G->fpucntl != RND_NEG_FPU) { - G->fpucntl = RND_NEG_FPU; - x87_fnclex(&G->f); - x86_mov_reg_imm(&G->f, G->r_eax, - (GLint) & G->mach->x86.fpucntl_rnd_neg); - x87_fldcw(&G->f, x86_deref(G->r_eax)); - } -} - -static void -emit_x87_ex2(codegen_ctx * G) -{ - set_fpu_round_neg_inf(G); - - x87_fld(&G->f, G->r_st0); /* a a */ - x87_fprndint(&G->f); /* int(a) a */ - x87_fld(&G->f, G->r_st0); /* int(a) int(a) a */ - x87_fstp(&G->f, G->r_st3); /* int(a) a int(a) */ - x87_fsubp(&G->f, G->r_st1); /* frac(a) int(a) */ - x87_f2xm1(&G->f); /* (2^frac(a))-1 int(a) */ - x87_fld1(&G->f); /* 1 (2^frac(a))-1 int(a) */ - x87_faddp(&G->f, G->r_st1); /* 2^frac(a) int(a) */ - x87_fscale(&G->f); /* 2^a */ -} - -static void -emit_pow(codegen_ctx * G) -{ - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fyl2x(&G->f); - emit_x87_ex2(G); -} - -#endif - -static GLfloat -do_ceilf(GLfloat x) -{ - return CEILF(x); -} - -static GLfloat -do_floorf(GLfloat x) -{ - return FLOORF(x); -} - -static GLfloat -do_ftoi(GLfloat x) -{ - return (GLfloat) ((GLint) (x)); -} - -static GLfloat -do_powf(GLfloat y, GLfloat x) -{ - return (GLfloat) _mesa_pow((GLdouble) x, (GLdouble) y); -} - -static GLvoid -ensure_infolog_created(slang_info_log ** infolog) -{ - if (*infolog == NULL) { - *infolog = slang_alloc_malloc(sizeof(slang_info_log)); - if (*infolog == NULL) - return; - slang_info_log_construct(*infolog); - } -} - -static GLvoid -do_print_float(slang_info_log ** infolog, GLfloat x) -{ - _mesa_printf("slang print: %f\n", x); - ensure_infolog_created(infolog); - slang_info_log_print(*infolog, "%f", x); -} - -static GLvoid -do_print_int(slang_info_log ** infolog, GLfloat x) -{ - _mesa_printf("slang print: %d\n", (GLint) (x)); - ensure_infolog_created(infolog); - slang_info_log_print(*infolog, "%d", (GLint) (x)); -} - -static GLvoid -do_print_bool(slang_info_log ** infolog, GLfloat x) -{ - _mesa_printf("slang print: %s\n", (GLint) (x) ? "true" : "false"); - ensure_infolog_created(infolog); - slang_info_log_print(*infolog, "%s", (GLint) (x) ? "true" : "false"); -} - -#define FLOAT_ONE 0x3f800000 -#define FLOAT_ZERO 0 - -static GLvoid -codegen_assem(codegen_ctx * G, slang_assembly * a, slang_info_log ** infolog) -{ - GLint disp, i; - - switch (a->type) { - case slang_asm_none: - break; - case slang_asm_float_copy: - case slang_asm_int_copy: - case slang_asm_bool_copy: - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0])); - x86_pop(&G->f, G->r_ecx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx); - break; - case slang_asm_float_move: - case slang_asm_int_move: - case slang_asm_bool_move: - x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[1])); - x86_add(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax)); - x86_mov(&G->f, x86_make_disp(G->r_esp, a->param[0]), G->r_eax); - break; - case slang_asm_float_push: - case slang_asm_int_push: - case slang_asm_bool_push: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, *((GLint *) & a->literal)); - x86_push(&G->f, G->r_eax); - break; - case slang_asm_float_deref: - case slang_asm_int_deref: - case slang_asm_bool_deref: - case slang_asm_addr_deref: - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax); - break; - case slang_asm_float_add: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_faddp(&G->f, G->r_st1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_multiply: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fmulp(&G->f, G->r_st1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_divide: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fdivp(&G->f, G->r_st1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_negate: - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fchs(&G->f); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_less: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fcomp(&G->f, x86_deref(G->r_esp)); - x87_fnstsw(&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x100); - x86_test(&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_equal_exp: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fcomp(&G->f, x86_deref(G->r_esp)); - x87_fnstsw(&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); - x86_test(&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_equal_int: - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4)); - x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4)); - x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4)); - x87_fnstsw(&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); - x86_test(&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_to_int: - /* TODO: use fistp without rounding */ - x86_call(&G->f, (GLubyte *) (do_ftoi)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_sine: - /* TODO: use fsin */ - x86_call(&G->f, (GLubyte *) _mesa_sinf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_arcsine: - /* TODO: use fpatan (?) */ - x86_call(&G->f, (GLubyte *) _mesa_asinf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_arctan: - /* TODO: use fpatan */ - x86_call(&G->f, (GLubyte *) _mesa_atanf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_power: - /* TODO: use emit_pow() */ - x86_call(&G->f, (GLubyte *) do_powf); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_log2: - x87_fld1(&G->f); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fyl2x(&G->f); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; -#if 00 - case slang_asm_float_floor: - x86_call(&G->f, (GLubyte *) do_floorf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; -#endif - case slang_asm_float_ceil: - x86_call(&G->f, (GLubyte *) do_ceilf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise1: - x86_call(&G->f, (GLubyte *) _slang_library_noise1); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise2: - x86_call(&G->f, (GLubyte *) _slang_library_noise2); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise3: - x86_call(&G->f, (GLubyte *) _slang_library_noise4); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 8)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise4: - x86_call(&G->f, (GLubyte *) _slang_library_noise4); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_int_to_float: - break; - case slang_asm_int_to_addr: - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fistp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_addr_copy: - x86_pop(&G->f, G->r_eax); - x86_mov(&G->f, G->r_ecx, x86_deref(G->r_esp)); - x86_mov(&G->f, x86_deref(G->r_ecx), G->r_eax); - break; - case slang_asm_addr_push: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) a->param[0]); - x86_push(&G->f, G->r_eax); - break; - case slang_asm_addr_add: - x86_pop(&G->f, G->r_eax); - x86_add(&G->f, x86_deref(G->r_esp), G->r_eax); - break; - case slang_asm_addr_multiply: - x86_pop(&G->f, G->r_ecx); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mul(&G->f, G->r_ecx); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax); - break; - case slang_asm_vec4_tex1d: - x86_call(&G->f, (GLubyte *) _slang_library_tex1d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12)); - break; - case slang_asm_vec4_tex2d: - x86_call(&G->f, (GLubyte *) _slang_library_tex2d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - break; - case slang_asm_vec4_tex3d: - x86_call(&G->f, (GLubyte *) _slang_library_tex3d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_vec4_texcube: - x86_call(&G->f, (GLubyte *) _slang_library_texcube); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_vec4_shad1d: - x86_call(&G->f, (GLubyte *) _slang_library_shad1d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_vec4_shad2d: - x86_call(&G->f, (GLubyte *) _slang_library_shad2d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_jump: - add_fixup(G, a->param[0], x86_jmp_forward(&G->f)); - break; - case slang_asm_jump_if_zero: - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_xor(&G->f, G->r_eax, G->r_eax); - x86_cmp(&G->f, G->r_eax, x86_make_disp(G->r_esp, -4)); - { - GLubyte *lab0; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_NE); - add_fixup(G, a->param[0], x86_jmp_forward(&G->f)); - x86_fixup_fwd_jump(&G->f, lab0); - } - break; - case slang_asm_enter: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert(a->param[0] != 0); - x86_push(&G->f, G->r_ebp); - x86_lea(&G->f, G->r_ebp, x86_make_disp(G->r_esp, (GLint) a->param[0])); - break; - case slang_asm_leave: - x86_pop(&G->f, G->r_ebp); - break; - case slang_asm_local_alloc: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert(a->param[0] != 0); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -(GLint) a->param[0])); - break; - case slang_asm_local_free: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert(a->param[0] != 0); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, (GLint) a->param[0])); - break; - case slang_asm_local_addr: - disp = -(GLint) (a->param[0] + a->param[1]) + 4; - if (disp != 0) { - x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_ebp, disp)); - x86_push(&G->f, G->r_eax); - } - else - x86_push(&G->f, G->r_ebp); - break; - case slang_asm_global_addr: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) & G->mach->mem + a->param[0]); - x86_push(&G->f, G->r_eax); - break; - case slang_asm_call: - add_fixup(G, a->param[0], x86_call_forward(&G->f)); - break; - case slang_asm_return: - x86_ret(&G->f); - break; - case slang_asm_discard: - x86_jmp(&G->f, G->l_discard); - break; - case slang_asm_exit: - x86_jmp(&G->f, G->l_exit); - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); - x86_push(&G->f, G->r_eax); - x86_call(&G->f, (GLubyte *) (do_print_float)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - break; - case slang_asm_int_print: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); - x86_push(&G->f, G->r_eax); - x86_call(&G->f, (GLubyte *) do_print_int); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - break; - case slang_asm_bool_print: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); - x86_push(&G->f, G->r_eax); - x86_call(&G->f, (GLubyte *) do_print_bool); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - break; - /* vec4 */ - case slang_asm_float_to_vec4: - /* [vec4] | float > [vec4] */ - x87_fld(&G->f, x86_deref(G->r_esp)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x87_fst(&G->f, x86_make_disp(G->r_eax, 12)); - x87_fst(&G->f, x86_make_disp(G->r_eax, 8)); - x87_fst(&G->f, x86_make_disp(G->r_eax, 4)); - x87_fstp(&G->f, x86_deref(G->r_eax)); - break; - case slang_asm_vec4_add: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_faddp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_subtract: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fsubp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_multiply: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fmulp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_divide: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fdivp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_negate: - /* [vec4] > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) { - x87_fchs(&G->f); - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - } - break; - case slang_asm_vec4_dot: - /* [vec4] | vec4 > [float] */ - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fmulp(&G->f, G->r_st4); - for (i = 0; i < 3; i++) - x87_faddp(&G->f, G->r_st1); - x87_fstp(&G->f, x86_deref(G->r_eax)); - break; - case slang_asm_vec4_copy: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0])); - x86_pop(&G->f, G->r_ecx); - x86_pop(&G->f, G->r_edx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx); - x86_pop(&G->f, G->r_ebx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 4), G->r_edx); - x86_pop(&G->f, G->r_ecx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 8), G->r_ebx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 12), G->r_ecx); - break; - case slang_asm_vec4_deref: - /* [vec4] > vec4 */ - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mov(&G->f, G->r_ecx, x86_make_disp(G->r_eax, 12)); - x86_mov(&G->f, G->r_edx, x86_make_disp(G->r_eax, 8)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - x86_mov(&G->f, G->r_ebx, x86_make_disp(G->r_eax, 4)); - x86_push(&G->f, G->r_edx); - x86_mov(&G->f, G->r_ecx, x86_deref(G->r_eax)); - x86_push(&G->f, G->r_ebx); - x86_push(&G->f, G->r_ecx); - break; - case slang_asm_vec4_equal_int: - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4)); - x86_mov_reg_imm(&G->f, G->r_edx, 0x4000); - for (i = 0; i < 4; i++) { - x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4 + i * 4)); - x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4 + i * 4)); - x87_fnstsw(&G->f, G->r_eax); - x86_and(&G->f, G->r_edx, G->r_eax); - } - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); - x86_test(&G->f, G->r_edx, G->r_ecx); - { - GLubyte *lab0, *lab1; - - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - default: - _mesa_problem(NULL, "Unexpected switch case in codegen_assem"); - } -} - -GLboolean -_slang_x86_codegen(slang_machine * mach, slang_assembly_file * file, - GLuint start) -{ - codegen_ctx G; - GLubyte *j_body, *j_exit; - GLuint i; - - /* Free the old code - if any. - */ - if (mach->x86.compiled_func != NULL) { - _mesa_exec_free(mach->x86.compiled_func); - mach->x86.compiled_func = NULL; - } - - /* - * We need as much as 1M because *all* assembly, including built-in library, is - * being translated to x86. - * The built-in library occupies 450K, so we can be safe for now. - * It is going to change in the future, when we get assembly analysis running. - */ - x86_init_func_size(&G.f, 1048576); - G.r_eax = x86_make_reg(file_REG32, reg_AX); - G.r_ecx = x86_make_reg(file_REG32, reg_CX); - G.r_edx = x86_make_reg(file_REG32, reg_DX); - G.r_ebx = x86_make_reg(file_REG32, reg_BX); - G.r_esp = x86_make_reg(file_REG32, reg_SP); - G.r_ebp = x86_make_reg(file_REG32, reg_BP); - G.r_st0 = x86_make_reg(file_x87, 0); - G.r_st1 = x86_make_reg(file_x87, 1); - G.r_st2 = x86_make_reg(file_x87, 2); - G.r_st3 = x86_make_reg(file_x87, 3); - G.r_st4 = x86_make_reg(file_x87, 4); - G.fixups = NULL; - G.fixup_count = 0; - G.labels = - (GLubyte **) slang_alloc_malloc(file->count * sizeof(GLubyte *)); - G.mach = mach; - G.fpucntl = RESTORE_FPU; - - mach->x86.fpucntl_rnd_neg = RND_NEG_FPU; - mach->x86.fpucntl_restore = RESTORE_FPU; - - /* prepare stack and jump to start */ - x86_push(&G.f, G.r_ebp); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore); - x86_push(&G.f, G.r_esp); - x86_pop(&G.f, G.r_ecx); - x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx); - j_body = x86_jmp_forward(&G.f); - - /* "discard" instructions jump to this label */ - G.l_discard = x86_get_label(&G.f); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->kill); - x86_mov_reg_imm(&G.f, G.r_ecx, 1); - x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx); - G.l_exit = x86_get_label(&G.f); - j_exit = x86_jmp_forward(&G.f); - - for (i = 0; i < file->count; i++) { - G.labels[i] = x86_get_label(&G.f); - if (i == start) - x86_fixup_fwd_jump(&G.f, j_body); - codegen_assem(&G, &file->code[i], &mach->infolog); - } - - /* - * Restore stack and return. - * This must be handled this way, because "discard" can be invoked from any - * place in the code. - */ - x86_fixup_fwd_jump(&G.f, j_exit); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore); - x86_mov(&G.f, G.r_esp, x86_deref(G.r_eax)); - x86_pop(&G.f, G.r_ebp); - if (G.fpucntl != RESTORE_FPU) { - x87_fnclex(&G.f); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->x86.fpucntl_restore); - x87_fldcw(&G.f, x86_deref(G.r_eax)); - } - x86_ret(&G.f); - - /* fixup forward labels */ - for (i = 0; i < G.fixup_count; i++) { - G.f.csr = G.labels[G.fixups[i].index]; - x86_fixup_fwd_jump(&G.f, G.fixups[i].csr); - } - - slang_alloc_free(G.fixups); - slang_alloc_free(G.labels); - - /* install new code */ - mach->x86.compiled_func = (GLvoid(*)(slang_machine *)) x86_get_func(&G.f); - - return GL_TRUE; -} - -#endif |