mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 10:40:11 +01:00
Remove obsolete files.
This commit is contained in:
parent
650d46a107
commit
ccd3e7dcef
3 changed files with 0 additions and 1669 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Reference in a new issue