/* asmrevdct.S */

#include "dct_const.h"

#define PASS1_BITS	1

#ifndef ADJUST
#define ADJUST	0
#endif

	.text

	.globl	_asm_rev_dct

/* asm_rev_dct(d,s) */

#define PAR_S		20(%esp)
#define PAR_B		24(%esp)
	.align	2

	.lcomm	tmp0,4
	.lcomm	tmp1,4
	.lcomm	tmp2,4
	.lcomm	tmp3,4
	.lcomm	tmp10,4
	.lcomm	tmp11,4
	.lcomm	tmp12,4
	.lcomm	tmp13,4
	.lcomm	count,1
	.lcomm	mask,1

#define DREG	%edi
#define I	%eax
#define J	%ebx
#define K	%ecx
#define L	%edx
#define M	%esi
#define N	%ebp

	.align	2
_asm_rev_dct:
	pushl	%ebp
	pushl	%edi
	pushl	%esi
	pushl	%ebx

	movl	PAR_B,DREG

	cmpl	$0,PAR_S
	jz	r_nosparse
	movswl	(DREG),%ebx
	addl	$4,%ebx
	sarl	$3+ADJUST,%ebx
#ifdef DCT_EIGHT
	addb	$96,%bl
	movb	%bl,%al
	movb	%bl,%ah
	shll	$16,%eax
	movb	%bl,%al
	movb	%bl,%ah
	movl	%eax,0*16(DREG)
	movl	%eax,0*16+4(DREG)
	movl	%eax,1*16(DREG)
	movl	%eax,1*16+4(DREG)
	movl	%eax,2*16(DREG)
	movl	%eax,2*16+4(DREG)
	movl	%eax,3*16(DREG)
	movl	%eax,3*16+4(DREG)
	movl	%eax,4*16(DREG)
	movl	%eax,4*16+4(DREG)
	movl	%eax,5*16(DREG)
	movl	%eax,5*16+4(DREG)
	movl	%eax,6*16(DREG)
	movl	%eax,6*16+4(DREG)
	movl	%eax,7*16(DREG)
	movl	%eax,7*16+4(DREG)
#else
	movzwl	%bx,%eax
	shll	$16,%ebx
	orl	%ebx,%eax
	movl	$32,%ecx
	rep
	stosl
#endif
	jmp	r_theend

	.align	2

r_nosparse:

#define SHIFT		(-PASS1_BITS)
#define INCFIRST	16
#define INCSECOND	2
#define Y(x)		r_l1_##x##:
#define Z(x)		r_l1_##x
#define ZEROCHECK1
#define PASS		1
#undef EIGHT_OUTPUT

#include "dct.S"

	subl	$8*INCSECOND,DREG

#undef SHIFT
#undef INCFIRST
#undef INCSECOND
#undef Y
#undef Z
#undef PASS

#define SHIFT		(PASS1_BITS+3+ADJUST)
#define INCFIRST	2
#define INCSECOND	16
#define Y(x)		r_l2_##x##:
#define Z(x)		r_l2_##x
#undef ZEROCHECK1
#define PASS		2
#ifdef DCT_EIGHT
#define EIGHT_OUTPUT
#endif

#include "dct.S"

#undef SHIFT
#undef INCFIRST
#undef INCSECOND
#undef Y
#undef Z
#undef PASS
#undef EIGHT_OUTPUT

r_theend:
	popl	%ebx
	popl	%esi
	popl	%edi
	popl	%ebp
	ret
