示例#1
0
文件: dyncode.c 项目: Jsoucek/q3ce
dyninst* Label(bool_t DoPost)
{
	dyninst* p = InstCreate(NULL,0,NONE,NONE,NONE,0,0);
	if (p) p->Branch = 1;
	if (DoPost) InstPost(p);
	return p;
}
示例#2
0
void PCMLoop(pcm_soft* p,bool_t Speed)
{
	bool_t SrcPacked = !(p->Src.Flags & PCM_PLANES) && p->Src.Channels==2;
	dyninst* Loop;
	reg Left;
	reg Right;
	reg Shift;

	if (!p->ActualDither && p->Shift)
		I1C(MOVI,R13,p->Shift);

	if (p->ActualDither)
		if (Speed)
			I2C(MOVL_STOFS,R7,SP,OFS(stack,Step)); // save backup
		else
			I1C(MOVI,R7,-p->Shift);

	Loop = Label(1);

	Left = R2;
	if (p->UseLeft)
		Right = R3;
	else
		Right = R2;

	if (Speed)
	{
		I2(MOV,R8,R0);
		IShift(R0,NONE,-8);
		IShift(R0,NONE,p->SrcShift);

		switch (p->Src.Bits)
		{
		case 8:
			if (p->UseLeft)
				I2(MOVB_LDR0,R9,Left);
			if (p->UseRight)
				I2(MOVB_LDR0,R10,Right);

			if (p->SrcUnsigned)	
			{
				I2(EXTUB,R2,R2);
				if (p->SrcChannels>1)
					I2(EXTUB,R3,R3);
			}
			break;

		case 16:
			if (p->UseLeft)
				I2(MOVW_LDR0,R9,Left);
			if (p->UseRight)
				I2(MOVW_LDR0,R10,Right);

			if (p->SrcUnsigned)	
			{
				I2(EXTUW,R2,R2);
				if (p->SrcChannels>1)
					I2(EXTUW,R3,R3);
			}
			break;

		case 32:
			if (p->UseLeft)
				I2(MOVL_LDR0,R9,Left);
			if (p->UseRight)
				I2(MOVL_LDR0,R10,Right);
			break;
		}

		I2(ADD,R7,R8);
	}
	else
	{
		switch (p->Src.Bits)
		{
		case 8:
			if (p->UseLeft)
			{
				I2(MOVB_LDADD,R9,Left);
				if (SrcPacked && !p->UseRight) I1C(ADDI,R9,1);
			}
			if (p->UseRight)
				if (SrcPacked)
				{
					if (!p->UseLeft) I1C(ADDI,R9,1);
					I2(MOVB_LDADD,R9,Right);
				}
				else
					I2(MOVB_LDADD,R10,Right);

			if (p->SrcUnsigned)	
			{
				I2(EXTUB,R2,R2);
				if (p->SrcChannels>1)
					I2(EXTUB,R3,R3);
			}
			break;

		case 16:
			if (p->UseLeft)
			{
				I2(MOVW_LDADD,R9,Left);
				if (SrcPacked && !p->UseRight) I1C(ADDI,R9,2);
			}
			if (p->UseRight)
				if (SrcPacked)
				{
					if (!p->UseLeft) I1C(ADDI,R9,2);
					I2(MOVW_LDADD,R9,Right);
				}
				else
					I2(MOVW_LDADD,R10,Right);

			if (p->SrcUnsigned)	
			{
				I2(EXTUW,R2,R2);
				if (p->SrcChannels>1)
					I2(EXTUW,R3,R3);
			}
			break;

		case 32:
			if (p->UseLeft)
			{
				I2(MOVL_LDADD,R9,Left);
				if (SrcPacked && !p->UseRight) I1C(ADDI,R9,4);
			}
			if (p->UseRight)
				if (SrcPacked)
				{
					if (!p->UseLeft) I1C(ADDI,R9,4);
					I2(MOVL_LDADD,R9,Right);
				}
				else
					I2(MOVL_LDADD,R10,Right);
			break;
		}
	}

	if (p->InstSrcUnsigned)
	{
		MB(); I1P(MOVL_PC,R0,p->InstSrcUnsigned,0);
		I2(SUB,R0,R2);
		if (p->SrcChannels>1)
			I2(SUB,R0,R3);
	}
	else
	if (p->SrcUnsigned == 128) 
	{
		I1C(ADDI,R2,-128);
		if (p->SrcChannels>1)
			I1C(ADDI,R3,-128);
	}

	if (p->Stereo)
	{
		if ((p->Src.Flags ^ p->Dst.Flags) & PCM_SWAPPEDSTEREO)
		{
			Left = R3;
			Right = R2;
		}
		else
		{
			Left = R2;
			Right = R3;
		}
	}
	else
	{
		if (p->Join)
			I2(ADD,R3,R2);
		Right = Left = R2;
	}


	if (p->ActualDither)
	{
		I2(ADD,R13,R2);
		I2(MOV,R2,R13);
		if (p->Stereo) 
		{
			I2(ADD,R1,R3);
			I2(MOV,R3,R1);
		}
	}

	if (p->Clip>0)
	{
		dyninst* ClipMin = Label(0);
		dyninst* ClipMax = Label(0);

		I2(CMPGT,R2,R4);
		I0P(BFS,ClipMin);
		I2(CMPGT,R5,R2); // delay slot
		I2(MOV,R4,R2);
		InstPost(ClipMin);

		I0P(BFS,ClipMax);
		I1C(ADDI,R11,1<<p->DstShift); // delay slot
		I2(MOV,R5,R2);
		InstPost(ClipMax);

		if (p->Stereo)
		{
			ClipMin = Label(0);
			ClipMax = Label(0);

			I2(CMPGT,R3,R4);
			I0P(BFS,ClipMin);
			I2(CMPGT,R5,R3); // delay slot
			I2(MOV,R4,R3);
			InstPost(ClipMin);

			I0P(BFS,ClipMax);
			I1C(ADDI,R12,1<<p->DstShift); // delay slot
			I2(MOV,R5,R3);
			InstPost(ClipMax);
		}
		else
		if (p->Dst.Channels>1)
			I1C(ADDI,R12,1<<p->DstShift); // delay slot
	}
	else
	{
		I1C(ADDI,R11,1<<p->DstShift);
		if (p->Dst.Channels>1)
			I1C(ADDI,R12,1<<p->DstShift);
	}

	I2(CMPEQ,R11,R14);

	if (p->Shift)
	{
		if (p->ActualDither)
		{
			I1C(MOVI,R0,p->Shift);
			Shift = R0;
		}
		else
			Shift = R13;
		I2(SHAD,Shift,R2);
		if (p->Stereo) I2(SHAD,Shift,R3);
	}

	if (p->ActualDither)
	{
		if (Speed)
			I1C(MOVI,R7,-p->Shift);

		I2(MOV,R2,R0);
		I2(SHAD,R7,R0);
		I2(SUB,R0,R13);
		if (p->Stereo)
		{
			I2(MOV,R3,R0);
			I2(SHAD,R7,R0);
			I2(SUB,R0,R1);
		}

		if (Speed)
			I2C(MOVL_LDOFS,SP,R7,OFS(stack,Step));
	}

	if (p->InstDstUnsigned)
	{
		MB(); I1P(MOVL_PC,R0,p->InstDstUnsigned,0);
		I1C(ADD,R0,Left);
		if (Left != Right)
			I1C(ADD,R0,Right);
	}
	else
	if (p->DstUnsigned == 128) 
	{
		// p->Dst.Bits=8 so doesn't matter if it's add or sub
		I1C(ADDI,Left,-128); 
		if (Left != Right)
			I1C(ADDI,Right,-128);
	}

	switch (p->Dst.Bits)
	{
	case 8:
		I2(MOVB_ST,Left,R11);
		if (p->Dst.Channels>1)
			I2(MOVB_ST,Right,R12);
		break;

	case 16:
		I2(MOVW_ST,Left,R11);
		if (p->Dst.Channels>1)
			I2(MOVW_ST,Right,R12);
		break;

	case 32:
		I2(MOVL_ST,Left,R11);
		if (p->Dst.Channels>1)
			I2(MOVL_ST,Right,R12);
		break;
	}

	DS(); I0P(BFS,Loop);

	if (p->ActualDither)
	{
		I2(MOV,SP,R0);
		I1C(ADDI,R0,OFS(stack,State));
		I2(MOVL_LD,R0,R4);

		I2C(MOVL_STOFS,R13,R4,OFS(pcmstate,Dither[0]));
		I2C(MOVL_STOFS,R1,R4,OFS(pcmstate,Dither[1]));
	}

	CodeEnd(7,OFS(stack,StackFrame));
}
示例#3
0
void PCMCompile(pcm_soft* p)
{
	dyninst* Speed;
	dyninst* Min = NULL;
	dyninst* Max = NULL;

	CodeBegin(7,OFS(stack,StackFrame));

	p->InstSrcUnsigned = NULL;
	p->InstDstUnsigned = NULL;

	if (p->SrcUnsigned && p->SrcUnsigned != 128)
		p->InstSrcUnsigned = InstCreate32(p->SrcUnsigned,NONE,NONE,NONE,0,0);
	if (p->DstUnsigned && p->DstUnsigned != 128)
		p->InstDstUnsigned = InstCreate32(p->DstUnsigned,NONE,NONE,NONE,0,0);

	// dst pointers
	I2C(MOVL_LDOFS,R5,R11,0);
	I1C(ADDI,R11,-(1<<p->DstShift)); // back one step

	if (p->Dst.Channels > 1)
	{
		if (p->Dst.Flags & PCM_PLANES)
		{
			I2C(MOVL_LDOFS,R5,R12,4);
			I1C(ADDI,R12,-(1<<p->DstShift)); // back one step
		}
		else
		{
			I2(MOV,R11,R12);
			I1C(ADDI,R12,1<<(p->DstShift-1));
		}
	}
	I2(MOV,R7,R14);
	I2(ADD,R11,R14); // dstend

	// src pointers
	I2C(MOVL_LDOFS,R6,R9,0);

	if (p->Src.Channels > 1)
	{
		if (p->Src.Flags & PCM_PLANES)
			I2C(MOVL_LDOFS,R6,R10,4);
		else
		{
			I2(MOV,R9,R10);
			I1C(ADDI,R10,p->Src.Bits>>3);
		}
	}

	I2(MOV,SP,R0);
	I1C(ADDI,R0,OFS(stack,State));
	I2(MOVL_LD,R0,R4);

	I2C(MOVL_LDOFS,R4,R7,OFS(pcmstate,Step));
	I2C(MOVL_LDOFS,R4,R8,OFS(pcmstate,Pos));

	/*
	if (p->UseVolume)
	{
		I1C(ADDI,R0,OFS(stack,Volume)-OFS(stack,State));
		I2(MOVL_LD,R0,R1);
	}
	*/

	if (p->ActualDither)
	{
		I2C(MOVL_LDOFS,R4,R13,OFS(pcmstate,Dither[0]));
		I2C(MOVL_LDOFS,R4,R1,OFS(pcmstate,Dither[1]));
	}

	if (p->Clip>0)
	{
		Min = InstCreate32(p->MinLimit,NONE,NONE,NONE,0,0);
		Max = InstCreate32(p->MaxLimit,NONE,NONE,NONE,0,0);

		I1P(MOVL_PC,R4,Min,0);
		I1P(MOVL_PC,R5,Max,0);
	}

	Speed = Label(0);

	I1C(MOVI,R2,64);
	I1(SHLL2,R2);
	I2(CMPEQ,R2,R7);
	I0P(BF,Speed);

	PCMLoop(p,0);

	InstPost(Speed);

	PCMLoop(p,1);

	Align(4);
	if (Min) InstPost(Min);
	if (Max) InstPost(Max);
	if (p->InstSrcUnsigned) InstPost(p->InstSrcUnsigned);
	if (p->InstDstUnsigned) InstPost(p->InstDstUnsigned);
}
示例#4
0
文件: dyncode.c 项目: Jsoucek/q3ce
void Align(int i)
{
	dyninst* p = InstCreate(NULL,-i,NONE,NONE,NONE,0,0);
	if (p) p->Branch = 1;
	InstPost(p);
}