	.section .ilm
	.align 2
	.globl spv40_iir_bqd_df1_stereo_q15_ofp
	.equ   FRAC_SAVING_BITS, 28
	.equ   OV_GUARDING_BITS, 1
# void spv40_iir_bqd_df1_stereo_q15_ofp(I32 len,							        a0
#										I32 *buffer,							    a1
#										I32 *coefs,		b0,b1,b2,-a1,-a2	        a2
#										I32	*states		lx1,lx2,ly1,ly2,lacc		a3
#                                               		rx1,rx2,ry1,ry2,racc    
#										)

# void spv40_iir_bqd_df1_stereo_q15_ofp(int32_t len, int32_t *buffer, int32_t *coefs, int32_t *states);
# buffer[]: LRLRLR...LRLR
# coefs[5]: b0, b1, b2, -a1, -a2 @ Q1.30 format
# states[10]
spv40_iir_bqd_df1_stereo_q15_ofp:
	addi 	sp,sp,-48
    sw		s0,44(sp)
    sw		s1,40(sp)
    sw		s2,36(sp)
    sw		s3,32(sp)
    sw		s4,28(sp)
    sw		s5,24(sp)
    sw		s6,20(sp)
    sw		s7,16(sp)
    sw		s8,12(sp)
    sw		s9,8(sp)
    sw		s10,4(sp)
    sw		s11,0(sp)

	LEA.w   tp,a1,a0				# tp = a1 + 4 * a0

	lw		s0,0(a3)				# s0: lx1
	lw		s1,4(a3)				# s1: lx2
	lw		s2,8(a3)				# s2: ly1
	lw		s3,12(a3)				# s3: ly2
	#(a4,a5) pair as left channel 64bit acc unit
	lw		a4,16(a3)				# a4: lacc
	mv		a5,zero

	lw		s4,20(a3)				# s4: rx1
	lw		s5,24(a3)				# s5: rx2
	lw		s6,28(a3)				# s6: ry1
	lw		s7,32(a3)				# s7: ry2
	#(a6,a7) pair as right channel 64bit acc unit
	lw		a6,36(a3)				# a6: racc
	mv		a7,zero

	lw 		t0,0(a2)				# t0: b0
	lw		t1,4(a2)				# t1: b1
	lw		t2,8(a2)				# t2: b2
	lw		t3,12(a2)				# t3: -a1
	lw		t4,16(a2)				# t4: -a2

loop:
	lh		s8,0(a1)				# s8: left channel input data  lx
	lh		s9,2(a1)				# s9: right channel input data rx
	addi	a1,a1,4

	SMAR64  a4,t2,s1				# lacc += b2 x lx2
	SMAR64  a6,t2,s5				# racc += b2 x rx2
	mv 		s1,s0					# lx2 = lx1
	mv 		s5,s4					# rx2 = rx1

	SMAR64	a4,t1,s0				# lacc += b1 x lx1
	SMAR64	a6,t1,s4				# racc += b1 x rx1
	mv 		s0,s8					# lx1 = lx
	mv 		s4,s9					# rx1 = rx

	SMAR64  a4,t0,s8				# lacc += b0 x lx
	SMAR64  a6,t0,s9				# racc += b0 x rx

	SMAR64  a4,t4,s3				# lacc += (-a2) x ly2
	SMAR64  a6,t4,s7				# racc += (-a2) x ry2
	mv 		s3,s2					# ly2 = ly1
	mv 		s7,s6					# ry2 = ry1

	SMAR64  a4,t3,s2				# lacc += (-a1) x ly1
	SMAR64  a6,t3,s6				# racc += (-a1) x ry1

	WEXTI	s2,a4,FRAC_SAVING_BITS	# ly1 = truncated ly
	WEXTI   s6,a6,FRAC_SAVING_BITS	# ry1 = truncated ry

	li		a5,0
	BFOZ	a4,a4,FRAC_SAVING_BITS-1,0				# update lacc
	SCLIP32	t6,s2,15
	sh		t6,-4(a1)				# store ly

	li		a7,0
	BFOZ	a6,a6,FRAC_SAVING_BITS-1,0				# update racc
	SCLIP32	t6,s6,15
	sh 		t6,-2(a1)				# store ry

	blt		a1,tp,loop

	sw		s0,0(a3)				# s0: lx1
	sw		s1,4(a3)				# s1: lx2
	sw		s2,8(a3)				# s2: ly1
	sw		s3,12(a3)				# s3: ly2
	sw		a4,16(a3)				# a4: lacc

	sw		s4,20(a3)				# s4: rx1
	sw		s5,24(a3)				# s5: rx2
	sw		s6,28(a3)				# s6: ry1
	sw		s7,32(a3)				# s7: ry2
	sw		a6,36(a3)				# a6: racc

    lw		s0,44(sp)
    lw		s1,40(sp)
    lw		s2,36(sp)
    lw		s3,32(sp)
    lw		s4,28(sp)
    lw		s5,24(sp)
    lw		s6,20(sp)
    lw		s7,16(sp)
    lw		s8,12(sp)
    lw		s9,8(sp)
    lw		s10,4(sp)
    lw		s11,0(sp)
    addi 	sp,sp,48
    ret
	
