From 9ac9605de156408580b81ba7e2780bd3f5372c6d Mon Sep 17 00:00:00 2001 From: Michal Krol Date: Mon, 27 Feb 2006 14:41:41 +0000 Subject: More GLSL code: - add x86 code generator; - add full support for uniforms in ARB_shader_objects; - add assembly instruction: global_addr; - reorganize #includes; - built-in uniforms accessed by index, rather than by name; - add some entries to x86sse rtasm; - add configurations to VC6 projects: 'Release x86' and 'Debug x86'; - #define SLANG_X86 active only on VC6 x86 builds; - introduce code export table for a shader; - remove GNU license from the noise library; --- src/mesa/x86/rtasm/x86sse.c | 83 +++++++++++++++++++++++++++++++++++++++------ src/mesa/x86/rtasm/x86sse.h | 32 +++++++++++++---- 2 files changed, 98 insertions(+), 17 deletions(-) (limited to 'src/mesa/x86') diff --git a/src/mesa/x86/rtasm/x86sse.c b/src/mesa/x86/rtasm/x86sse.c index 0c9ffe25fa2..82a18f012a1 100644 --- a/src/mesa/x86/rtasm/x86sse.c +++ b/src/mesa/x86/rtasm/x86sse.c @@ -1,4 +1,4 @@ -#if defined(USE_X86_ASM) +#if defined(USE_X86_ASM) || defined(SLANG_X86) #include "imports.h" #include "x86sse.h" @@ -85,10 +85,10 @@ static void emit_modrm( struct x86_function *p, case mod_INDIRECT: break; case mod_DISP8: - emit_1b(p, regmem.disp); + emit_1b(p, regmem.disp); break; case mod_DISP32: - emit_1i(p, regmem.disp); + emit_1i(p, regmem.disp); break; default: assert(0); @@ -142,8 +142,8 @@ static void emit_op_modrm( struct x86_function *p, /* Create and manipulate registers and regmem values: */ -struct x86_reg x86_make_reg( GLuint file, - GLuint idx ) +struct x86_reg x86_make_reg( enum x86_reg_file file, + enum x86_reg_name idx ) { struct x86_reg reg; @@ -198,7 +198,7 @@ GLubyte *x86_get_label( struct x86_function *p ) void x86_jcc( struct x86_function *p, - GLuint cc, + enum x86_cc cc, GLubyte *label ) { GLint offset = label - (x86_get_label(p) + 2); @@ -217,11 +217,25 @@ void x86_jcc( struct x86_function *p, /* Always use a 32bit offset for forward jumps: */ GLubyte *x86_jcc_forward( struct x86_function *p, - GLuint cc ) + enum x86_cc cc ) { emit_2ub(p, 0x0f, 0x80 + cc); emit_1i(p, 0); return x86_get_label(p); +} + +GLubyte *x86_jmp_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe9); + emit_1i(p, 0); + return x86_get_label(p); +} + +GLubyte *x86_call_forward( struct x86_function *p) +{ + emit_1ub(p, 0xe8); + emit_1i(p, 0); + return x86_get_label(p); } /* Fixup offset from forward jump: @@ -230,6 +244,29 @@ void x86_fixup_fwd_jump( struct x86_function *p, GLubyte *fixup ) { *(int *)(fixup - 4) = x86_get_label(p) - fixup; +} + +void x86_jmp( struct x86_function *p, GLubyte *label) +{ + emit_1ub(p, 0xe9); + emit_1i(p, label - x86_get_label(p) - 4); +} + +void x86_call( struct x86_function *p, GLubyte *label) +{ + emit_1ub(p, 0xe8); + emit_1i(p, label - x86_get_label(p) - 4); +} + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, GLint imm ) +{ + assert(dst.mod == mod_REG); + emit_1ub(p, 0xb8 + dst.idx); + emit_1i(p, imm); } void x86_push( struct x86_function *p, @@ -307,6 +344,27 @@ void x86_test( struct x86_function *p, { emit_1ub(p, 0x85); emit_modrm( p, dst, src ); +} + +void x86_add( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x03, 0x01, dst, src ); +} + +void x86_mul( struct x86_function *p, + struct x86_reg src ) +{ + assert (src.file == file_REG32 && src.mod == mod_REG); + emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src ); +} + +void x86_sub( struct x86_function *p, + struct x86_reg dst, + struct x86_reg src ) +{ + emit_op_modrm(p, 0x2b, 0x29, dst, src ); } @@ -971,8 +1029,13 @@ struct x86_reg x86_fn_arg( struct x86_function *p, void x86_init_func( struct x86_function *p ) { - p->store = _mesa_exec_malloc(1024); - p->csr = p->store; + x86_init_func_size(p, 1024); +} + +void x86_init_func_size( struct x86_function *p, GLuint code_size ) +{ + p->store = _mesa_exec_malloc(code_size); + p->csr = p->store; } void x86_release_func( struct x86_function *p ) @@ -985,7 +1048,7 @@ void (*x86_get_func( struct x86_function *p ))(void) { if (DISASSEM) _mesa_printf("disassemble %p %p\n", p->store, p->csr); - return (void (*)())p->store; + return (void (*)(void))p->store; } #else diff --git a/src/mesa/x86/rtasm/x86sse.h b/src/mesa/x86/rtasm/x86sse.h index 611d01e1cb3..55a98564afb 100644 --- a/src/mesa/x86/rtasm/x86sse.h +++ b/src/mesa/x86/rtasm/x86sse.h @@ -2,7 +2,7 @@ #ifndef _X86SSE_H_ #define _X86SSE_H_ -#if defined(USE_X86_ASM) +#if defined(USE_X86_ASM) || defined(SLANG_X86) #include "glheader.h" @@ -80,7 +80,8 @@ enum sse_cc { */ -void x86_init_func( struct x86_function *p ); +void x86_init_func( struct x86_function *p ); +void x86_init_func_size( struct x86_function *p, GLuint code_size ); void x86_release_func( struct x86_function *p ); void (*x86_get_func( struct x86_function *p ))( void ); @@ -108,10 +109,24 @@ void x86_jcc( struct x86_function *p, GLubyte *label ); GLubyte *x86_jcc_forward( struct x86_function *p, - enum x86_cc cc ); + enum x86_cc cc ); + +GLubyte *x86_jmp_forward( struct x86_function *p); + +GLubyte *x86_call_forward( struct x86_function *p); void x86_fixup_fwd_jump( struct x86_function *p, - GLubyte *fixup ); + GLubyte *fixup ); + +void x86_jmp( struct x86_function *p, GLubyte *label ); + +void x86_call( struct x86_function *p, GLubyte *label ); + +/* michal: + * Temporary. As I need immediate operands, and dont want to mess with the codegen, + * I load the immediate into general purpose register and use it. + */ +void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, GLint imm ); /* Macro for sse_shufps() and sse2_pshufd(): @@ -153,15 +168,18 @@ void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ) void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0, GLubyte shuf ); - + +void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_dec( struct x86_function *p, struct x86_reg reg ); void x86_inc( struct x86_function *p, struct x86_reg reg ); void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); -void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); +void x86_mul( struct x86_function *p, struct x86_reg src ); void x86_pop( struct x86_function *p, struct x86_reg reg ); void x86_push( struct x86_function *p, struct x86_reg reg ); -void x86_ret( struct x86_function *p ); +void x86_ret( struct x86_function *p ); +void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src ); void x86_sahf( struct x86_function *p ); -- cgit v1.2.3