make_xmm( xmm_src ) );
}
-
-
-
-
-
-
/**
* Register fetch.
*/
-
static void
emit_fetch(
struct x86_function *func,
/**
* Register store.
*/
-
static void
emit_store(
struct x86_function *func,
/**
* High-level instruction translators.
*/
-
static void
emit_tex( struct x86_function *func,
const struct tgsi_full_instruction *inst,
get_temp( TEMP_R0, 3 ),
make_xmm( 3 ) );
-
if (projected) {
FETCH( func, *inst, 3, 0, 3 );
args[0] = get_temp( TEMP_R0, 0 );
args[1] = get_sampler_ptr( unit );
-
emit_func_call( func,
0,
args,
/* This mask stores component bits that were already tested. Note that
* we test if the value is less than zero, so 1.0 and 0.0 need not to be
- * tested. */
+ * tested.
+ */
uniquemask = 0;
FOR_EACH_CHANNEL( chan_index ) {
/**
- * Check if inst src/dest regs use indirect addressing into temporary
- * register file.
+ * Check if inst src/dest regs use indirect addressing into temporary,
+ * input or output register files.
*/
static boolean
-indirect_temp_reference(const struct tgsi_full_instruction *inst)
+indirect_reg_reference(const struct tgsi_full_instruction *inst)
{
uint i;
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *reg = &inst->Src[i];
- if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+ if ((reg->Register.File == TGSI_FILE_TEMPORARY ||
+ reg->Register.File == TGSI_FILE_INPUT ||
+ reg->Register.File == TGSI_FILE_OUTPUT) &&
reg->Register.Indirect)
return TRUE;
}
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
const struct tgsi_full_dst_register *reg = &inst->Dst[i];
- if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+ if ((reg->Register.File == TGSI_FILE_TEMPORARY ||
+ reg->Register.File == TGSI_FILE_INPUT ||
+ reg->Register.File == TGSI_FILE_OUTPUT) &&
reg->Register.Indirect)
return TRUE;
}
unsigned chan_index;
/* we can't handle indirect addressing into temp register file yet */
- if (indirect_temp_reference(inst))
+ if (indirect_reg_reference(inst))
return FALSE;
switch (inst->Instruction.Opcode) {
break;
case TGSI_OPCODE_MUL:
+ /* do all fetches and adds, storing results in temp regs */
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( func, *inst, 0, 0, chan_index );
- FETCH( func, *inst, 1, 1, chan_index );
- emit_mul( func, 0, 1 );
- STORE( func, *inst, 0, 0, chan_index );
+ int r = chan_index + 1;
+ FETCH( func, *inst, 0, 0, chan_index ); /* load xmm[0] */
+ FETCH( func, *inst, r, 1, chan_index ); /* load xmm[r] */
+ emit_mul( func, r, 0 ); /* xmm[r] = xmm[r] * xmm[0] */
+ }
+ /* do all stores of the temp regs */
+ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
+ int r = chan_index + 1;
+ STORE( func, *inst, r, 0, chan_index ); /* store xmm[r] */
}
break;
case TGSI_OPCODE_ADD:
+ /* do all fetches and adds, storing results in temp regs */
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( func, *inst, 0, 0, chan_index );
- FETCH( func, *inst, 1, 1, chan_index );
- emit_add( func, 0, 1 );
- STORE( func, *inst, 0, 0, chan_index );
+ int r = chan_index + 1;
+ FETCH( func, *inst, 0, 0, chan_index ); /* load xmm[0] */
+ FETCH( func, *inst, r, 1, chan_index ); /* load xmm[r] */
+ emit_add( func, r, 0 ); /* xmm[r] = xmm[r] + xmm[0] */
+ }
+ /* do all stores of the temp regs */
+ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
+ int r = chan_index + 1;
+ STORE( func, *inst, r, 0, chan_index ); /* store xmm[r] */
}
break;
check_soa_dependencies(const struct tgsi_full_instruction *inst)
{
switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_ADD:
+ case TGSI_OPCODE_MOV:
+ case TGSI_OPCODE_MUL:
case TGSI_OPCODE_XPD:
- /* OK */
+ /* OK - these opcodes correctly handle SOA dependencies */
break;
default:
if (tgsi_check_soa_dependencies(inst)) {
x86_make_disp( get_machine_base(),
Offset( struct tgsi_exec_machine, Samplers ) ) );
-
while( !tgsi_parse_end_of_tokens( &parse ) && ok ) {
tgsi_parse_token( &parse );
}
#endif /* PIPE_ARCH_X86 */
-