bool ExpandMachineInstruction()
{
// now push instructions onto MachineInstructions container
// assume that an instruction will be expanded
bool passed = true;
if ( opType != MachineInstruction.Nop )
{
// a machine instruction will be built
// this is currently the last one being built so keep track of it
if ( instructionPhase == PhaseType.PHASE2ALU )
{
secondLastInstructionPos = lastInstructionPos;
lastInstructionPos = phase2ALU_mi.Count;
}
switch ( opType )
{
case MachineInstruction.ColorOp1:
case MachineInstruction.ColorOp2:
case MachineInstruction.ColorOp3:
{
AddMachineInst( instructionPhase, (int)opType );
AddMachineInst( instructionPhase, symbolTypeLib[ (int)opInst ].pass2Data );
// send all parameters to machine inst container
for ( int i = 0; i <= argCnt; i++ )
{
AddMachineInst( instructionPhase, opParams[ i ].Arg );
AddMachineInst( instructionPhase, (int)opParams[ i ].MaskRep );
AddMachineInst( instructionPhase, opParams[ i ].Mod );
// check if source register read is valid in this phase
passed &= IsRegisterReadValid( instructionPhase, i );
}
// record which registers were written to and in which phase
// opParams[0].Arg is always the destination register r0 -> r5
UpdateRegisterWriteState( instructionPhase );
}
break;
case MachineInstruction.SetConstants:
AddMachineInst( instructionPhase, (int)opType );
AddMachineInst( instructionPhase, opParams[ 0 ].Arg ); // dst
AddMachineInst( instructionPhase, constantsPos ); // index into constants array
break;
case MachineInstruction.PassTexCoord:
case MachineInstruction.SampleMap:
// if source is a temp register than place instruction in phase 2 Texture ops
if ( ( opParams[ 1 ].Arg >= Gl.GL_REG_0_ATI ) && ( opParams[ 1 ].Arg <= Gl.GL_REG_5_ATI ) )
{
instructionPhase = PhaseType.PHASE2TEX;
}
AddMachineInst( instructionPhase, (int)opType );
AddMachineInst( instructionPhase, opParams[ 0 ].Arg ); // dst
AddMachineInst( instructionPhase, opParams[ 1 ].Arg ); // coord
AddMachineInst( instructionPhase, (int)opParams[ 1 ].MaskRep + Gl.GL_SWIZZLE_STR_ATI ); // swizzle
// record which registers were written to and in which phase
// opParams[0].Arg is always the destination register r0 -> r5
UpdateRegisterWriteState( instructionPhase );
break;
case MachineInstruction.Tex: // PS_1_1 emulation - turn CISC into RISC - phase 1
AddMachineInst( instructionPhase, (int)MachineInstruction.SampleMap );
AddMachineInst( instructionPhase, opParams[ 0 ].Arg ); // dst
// tex tx becomes texld rx, tx with x: 0 - 3
AddMachineInst( instructionPhase, opParams[ 0 ].Arg - Gl.GL_REG_0_ATI + Gl.GL_TEXTURE0_ARB ); // interp
// default to str which fills rgb of destination register
AddMachineInst( instructionPhase, Gl.GL_SWIZZLE_STR_ATI ); // swizzle
// record which registers were written to and in which phase
// opParams[0].Arg is always the destination register r0 -> r5
UpdateRegisterWriteState( instructionPhase );
break;
case MachineInstruction.TexCoord: // PS_1_1 emulation - turn CISC into RISC - phase 1
AddMachineInst( instructionPhase, (int)MachineInstruction.PassTexCoord );
AddMachineInst( instructionPhase, opParams[ 0 ].Arg ); // dst
// texcoord tx becomes texcrd rx, tx with x: 0 - 3
AddMachineInst( instructionPhase, opParams[ 0 ].Arg - Gl.GL_REG_0_ATI + Gl.GL_TEXTURE0_ARB ); // interp
// default to str which fills rgb of destination register
AddMachineInst( instructionPhase, Gl.GL_SWIZZLE_STR_ATI ); // swizzle
// record which registers were written to and in which phase
// opParams[0].Arg is always the destination register r0 -> r5
UpdateRegisterWriteState( instructionPhase );
break;
} // end of switch (opType)
} // end of if (opType != mi_NOP)
if ( do_Alpha )
{
// process alpha channel
//
// a scaler machine instruction will be built
// this is currently the last one being built so keep track of it
if ( instructionPhase == PhaseType.PHASE2ALU )
{
secondLastInstructionPos = lastInstructionPos;
lastInstructionPos = phase2ALU_mi.Count;
}
MachineInstruction alphaoptype = (MachineInstruction)( MachineInstruction.AlphaOp1 + argCnt - 1 );
AddMachineInst( instructionPhase, (int)alphaoptype );
AddMachineInst( instructionPhase, symbolTypeLib[ (int)opInst ].pass2Data );
// put all parameters in instruction que
for ( int i = 0; i <= argCnt; i++ )
{
AddMachineInst( instructionPhase, opParams[ i ].Arg );
// destination parameter has no mask since it is the alpha channel
// don't push mask for parrameter 0 (dst)
if ( i > 0 )
{
AddMachineInst( instructionPhase, (int)opParams[ i ].MaskRep );
}
AddMachineInst( instructionPhase, opParams[ i ].Mod );
// check if source register read is valid in this phase
passed &= IsRegisterReadValid( instructionPhase, i );
}
UpdateRegisterWriteState( instructionPhase );
}
// instruction passed on to machine instruction so clear the pipe
ClearMachineInstState();
return passed;
}