diff options
Diffstat (limited to 'src/gallium/auxiliary/tgsi/tgsi_sse2.c')
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_sse2.c | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index cfe8ef0ecf..5928f874a9 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -533,17 +533,13 @@ emit_coef_dady( static void emit_func_call( struct x86_function *func, - unsigned xmm_save, - unsigned xmm_dst, + unsigned xmm_save_mask, + const struct x86_reg *arg, + unsigned nr_args, void (PIPE_CDECL *code)() ) { struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX ); unsigned i, n; - unsigned xmm_mask; - - /* Bitmask of the xmm registers to save */ - xmm_mask = (1 << xmm_save) - 1; - xmm_mask &= ~(1 << xmm_dst); x86_push( func, @@ -558,7 +554,7 @@ emit_func_call( /* Store XMM regs to the stack */ for(i = 0, n = 0; i < 8; ++i) - if(xmm_mask & (1 << i)) + if(xmm_save_mask & (1 << i)) ++n; x86_sub_imm( @@ -567,35 +563,42 @@ emit_func_call( n*16); for(i = 0, n = 0; i < 8; ++i) - if(xmm_mask & (1 << i)) { + if(xmm_save_mask & (1 << i)) { sse_movups( func, x86_make_disp( x86_make_reg( file_REG32, reg_SP ), n*16 ), make_xmm( i ) ); ++n; } + + for (i = 0; i < nr_args; i++) { + /* Load the address of the buffer we use for passing arguments and + * receiving results: + */ + x86_lea( + func, + ecx, + arg[i] ); - /* Load the address of the buffer we use for passing arguments and - * receiving results: - */ - x86_lea( - func, - ecx, - get_temp( TEMP_R0, 0 ) ); - - /* Push actual function arguments (currently just the pointer to - * the buffer above), and call the function: - */ - x86_push( func, ecx ); + /* Push actual function arguments (currently just the pointer to + * the buffer above), and call the function: + */ + x86_push( func, ecx ); + } + x86_mov_reg_imm( func, ecx, (unsigned long) code ); x86_call( func, ecx ); - x86_pop(func, ecx ); - + + /* Pop the arguments (or just add an immediate to esp) + */ + for (i = 0; i < nr_args; i++) { + x86_pop(func, ecx ); + } /* Pop the saved XMM regs: */ for(i = 0, n = 0; i < 8; ++i) - if(xmm_mask & (1 << i)) { + if(xmm_save_mask & (1 << i)) { sse_movups( func, make_xmm( i ), @@ -621,7 +624,6 @@ emit_func_call( x86_make_reg( file_REG32, reg_AX) ); } - static void emit_func_call_dst_src1( struct x86_function *func, @@ -630,25 +632,28 @@ emit_func_call_dst_src1( unsigned xmm_src0, void (PIPE_CDECL *code)() ) { + struct x86_reg store = get_temp( TEMP_R0, 0 ); + unsigned xmm_mask = ((1 << xmm_save) - 1) & ~(1 << xmm_dst); + /* Store our input parameters (in xmm regs) to the buffer we use * for passing arguments. We will pass a pointer to this buffer as * the actual function argument. */ sse_movaps( func, - get_temp( TEMP_R0, 0 ), + store, make_xmm( xmm_src0 ) ); - emit_func_call( - func, - xmm_save, - xmm_dst, - code ); + emit_func_call( func, + xmm_mask, + &store, + 1, + code ); sse_movaps( func, make_xmm( xmm_dst ), - get_temp( TEMP_R0, 0 ) ); + store ); } @@ -661,33 +666,36 @@ emit_func_call_dst_src2( unsigned xmm_src1, void (PIPE_CDECL *code)() ) { + struct x86_reg store = get_temp( TEMP_R0, 0 ); + unsigned xmm_mask = ((1 << xmm_save) - 1) & ~(1 << xmm_dst); + /* Store two inputs to parameter buffer. */ sse_movaps( func, - get_temp( TEMP_R0, 0 ), + store, make_xmm( xmm_src0 ) ); sse_movaps( func, - get_temp( TEMP_R0, 1 ), + x86_make_disp( store, 4 * sizeof(float) ), make_xmm( xmm_src1 ) ); /* Emit the call */ - emit_func_call( - func, - xmm_save, - xmm_dst, - code ); + emit_func_call( func, + xmm_mask, + &store, + 1, + code ); /* Retrieve the results: */ sse_movaps( func, make_xmm( xmm_dst ), - get_temp( TEMP_R0, 0 ) ); + store ); } |