Linux Audio

Check our new training course

Loading...
v3.1
 
  1/*---------------------------------------------------------------------------+
  2 |  polynomial_Xsig.S                                                        |
  3 |                                                                           |
  4 | Fixed point arithmetic polynomial evaluation.                             |
  5 |                                                                           |
  6 | Copyright (C) 1992,1993,1994,1995                                         |
  7 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  8 |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
  9 |                                                                           |
 10 | Call from C as:                                                           |
 11 |   void polynomial_Xsig(Xsig *accum, unsigned long long x,                 |
 12 |                        unsigned long long terms[], int n)                 |
 13 |                                                                           |
 14 | Computes:                                                                 |
 15 | terms[0] + (terms[1] + (terms[2] + ... + (terms[n-1]*x)*x)*x)*x) ... )*x  |
 16 | and adds the result to the 12 byte Xsig.                                  |
 17 | The terms[] are each 8 bytes, but all computation is performed to 12 byte |
 18 | precision.                                                                |
 19 |                                                                           |
 20 | This function must be used carefully: most overflow of intermediate       |
 21 | results is controlled, but overflow of the result is not.                 |
 22 |                                                                           |
 23 +---------------------------------------------------------------------------*/
 24	.file	"polynomial_Xsig.S"
 25
 26#include "fpu_emu.h"
 27
 28
 29#define	TERM_SIZE	$8
 30#define	SUM_MS		-20(%ebp)	/* sum ms long */
 31#define SUM_MIDDLE	-24(%ebp)	/* sum middle long */
 32#define	SUM_LS		-28(%ebp)	/* sum ls long */
 33#define	ACCUM_MS	-4(%ebp)	/* accum ms long */
 34#define	ACCUM_MIDDLE	-8(%ebp)	/* accum middle long */
 35#define	ACCUM_LS	-12(%ebp)	/* accum ls long */
 36#define OVERFLOWED      -16(%ebp)	/* addition overflow flag */
 37
 38.text
 39ENTRY(polynomial_Xsig)
 40	pushl	%ebp
 41	movl	%esp,%ebp
 42	subl	$32,%esp
 43	pushl	%esi
 44	pushl	%edi
 45	pushl	%ebx
 46
 47	movl	PARAM2,%esi		/* x */
 48	movl	PARAM3,%edi		/* terms */
 49
 50	movl	TERM_SIZE,%eax
 51	mull	PARAM4			/* n */
 52	addl	%eax,%edi
 53
 54	movl	4(%edi),%edx		/* terms[n] */
 55	movl	%edx,SUM_MS
 56	movl	(%edi),%edx		/* terms[n] */
 57	movl	%edx,SUM_MIDDLE
 58	xor	%eax,%eax
 59	movl	%eax,SUM_LS
 60	movb	%al,OVERFLOWED
 61
 62	subl	TERM_SIZE,%edi
 63	decl	PARAM4
 64	js	L_accum_done
 65
 66L_accum_loop:
 67	xor	%eax,%eax
 68	movl	%eax,ACCUM_MS
 69	movl	%eax,ACCUM_MIDDLE
 70
 71	movl	SUM_MIDDLE,%eax
 72	mull	(%esi)			/* x ls long */
 73	movl	%edx,ACCUM_LS
 74
 75	movl	SUM_MIDDLE,%eax
 76	mull	4(%esi)			/* x ms long */
 77	addl	%eax,ACCUM_LS
 78	adcl	%edx,ACCUM_MIDDLE
 79	adcl	$0,ACCUM_MS
 80
 81	movl	SUM_MS,%eax
 82	mull	(%esi)			/* x ls long */
 83	addl	%eax,ACCUM_LS
 84	adcl	%edx,ACCUM_MIDDLE
 85	adcl	$0,ACCUM_MS
 86
 87	movl	SUM_MS,%eax
 88	mull	4(%esi)			/* x ms long */
 89	addl	%eax,ACCUM_MIDDLE
 90	adcl	%edx,ACCUM_MS
 91
 92	testb	$0xff,OVERFLOWED
 93	jz	L_no_overflow
 94
 95	movl	(%esi),%eax
 96	addl	%eax,ACCUM_MIDDLE
 97	movl	4(%esi),%eax
 98	adcl	%eax,ACCUM_MS		/* This could overflow too */
 99
100L_no_overflow:
101
102/*
103 * Now put the sum of next term and the accumulator
104 * into the sum register
105 */
106	movl	ACCUM_LS,%eax
107	addl	(%edi),%eax		/* term ls long */
108	movl	%eax,SUM_LS
109	movl	ACCUM_MIDDLE,%eax
110	adcl	(%edi),%eax		/* term ls long */
111	movl	%eax,SUM_MIDDLE
112	movl	ACCUM_MS,%eax
113	adcl	4(%edi),%eax		/* term ms long */
114	movl	%eax,SUM_MS
115	sbbb	%al,%al
116	movb	%al,OVERFLOWED		/* Used in the next iteration */
117
118	subl	TERM_SIZE,%edi
119	decl	PARAM4
120	jns	L_accum_loop
121
122L_accum_done:
123	movl	PARAM1,%edi		/* accum */
124	movl	SUM_LS,%eax
125	addl	%eax,(%edi)
126	movl	SUM_MIDDLE,%eax
127	adcl	%eax,4(%edi)
128	movl	SUM_MS,%eax
129	adcl	%eax,8(%edi)
130
131	popl	%ebx
132	popl	%edi
133	popl	%esi
134	leave
135	ret
 
v6.13.7
  1/* SPDX-License-Identifier: GPL-2.0 */
  2/*---------------------------------------------------------------------------+
  3 |  polynomial_Xsig.S                                                        |
  4 |                                                                           |
  5 | Fixed point arithmetic polynomial evaluation.                             |
  6 |                                                                           |
  7 | Copyright (C) 1992,1993,1994,1995                                         |
  8 |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  9 |                       Australia.  E-mail billm@jacobi.maths.monash.edu.au |
 10 |                                                                           |
 11 | Call from C as:                                                           |
 12 |   void polynomial_Xsig(Xsig *accum, unsigned long long x,                 |
 13 |                        unsigned long long terms[], int n)                 |
 14 |                                                                           |
 15 | Computes:                                                                 |
 16 | terms[0] + (terms[1] + (terms[2] + ... + (terms[n-1]*x)*x)*x)*x) ... )*x  |
 17 | and adds the result to the 12 byte Xsig.                                  |
 18 | The terms[] are each 8 bytes, but all computation is performed to 12 byte |
 19 | precision.                                                                |
 20 |                                                                           |
 21 | This function must be used carefully: most overflow of intermediate       |
 22 | results is controlled, but overflow of the result is not.                 |
 23 |                                                                           |
 24 +---------------------------------------------------------------------------*/
 25	.file	"polynomial_Xsig.S"
 26
 27#include "fpu_emu.h"
 28
 29
 30#define	TERM_SIZE	$8
 31#define	SUM_MS		-20(%ebp)	/* sum ms long */
 32#define SUM_MIDDLE	-24(%ebp)	/* sum middle long */
 33#define	SUM_LS		-28(%ebp)	/* sum ls long */
 34#define	ACCUM_MS	-4(%ebp)	/* accum ms long */
 35#define	ACCUM_MIDDLE	-8(%ebp)	/* accum middle long */
 36#define	ACCUM_LS	-12(%ebp)	/* accum ls long */
 37#define OVERFLOWED      -16(%ebp)	/* addition overflow flag */
 38
 39.text
 40SYM_FUNC_START(polynomial_Xsig)
 41	pushl	%ebp
 42	movl	%esp,%ebp
 43	subl	$32,%esp
 44	pushl	%esi
 45	pushl	%edi
 46	pushl	%ebx
 47
 48	movl	PARAM2,%esi		/* x */
 49	movl	PARAM3,%edi		/* terms */
 50
 51	movl	TERM_SIZE,%eax
 52	mull	PARAM4			/* n */
 53	addl	%eax,%edi
 54
 55	movl	4(%edi),%edx		/* terms[n] */
 56	movl	%edx,SUM_MS
 57	movl	(%edi),%edx		/* terms[n] */
 58	movl	%edx,SUM_MIDDLE
 59	xor	%eax,%eax
 60	movl	%eax,SUM_LS
 61	movb	%al,OVERFLOWED
 62
 63	subl	TERM_SIZE,%edi
 64	decl	PARAM4
 65	js	L_accum_done
 66
 67L_accum_loop:
 68	xor	%eax,%eax
 69	movl	%eax,ACCUM_MS
 70	movl	%eax,ACCUM_MIDDLE
 71
 72	movl	SUM_MIDDLE,%eax
 73	mull	(%esi)			/* x ls long */
 74	movl	%edx,ACCUM_LS
 75
 76	movl	SUM_MIDDLE,%eax
 77	mull	4(%esi)			/* x ms long */
 78	addl	%eax,ACCUM_LS
 79	adcl	%edx,ACCUM_MIDDLE
 80	adcl	$0,ACCUM_MS
 81
 82	movl	SUM_MS,%eax
 83	mull	(%esi)			/* x ls long */
 84	addl	%eax,ACCUM_LS
 85	adcl	%edx,ACCUM_MIDDLE
 86	adcl	$0,ACCUM_MS
 87
 88	movl	SUM_MS,%eax
 89	mull	4(%esi)			/* x ms long */
 90	addl	%eax,ACCUM_MIDDLE
 91	adcl	%edx,ACCUM_MS
 92
 93	testb	$0xff,OVERFLOWED
 94	jz	L_no_overflow
 95
 96	movl	(%esi),%eax
 97	addl	%eax,ACCUM_MIDDLE
 98	movl	4(%esi),%eax
 99	adcl	%eax,ACCUM_MS		/* This could overflow too */
100
101L_no_overflow:
102
103/*
104 * Now put the sum of next term and the accumulator
105 * into the sum register
106 */
107	movl	ACCUM_LS,%eax
108	addl	(%edi),%eax		/* term ls long */
109	movl	%eax,SUM_LS
110	movl	ACCUM_MIDDLE,%eax
111	adcl	(%edi),%eax		/* term ls long */
112	movl	%eax,SUM_MIDDLE
113	movl	ACCUM_MS,%eax
114	adcl	4(%edi),%eax		/* term ms long */
115	movl	%eax,SUM_MS
116	sbbb	%al,%al
117	movb	%al,OVERFLOWED		/* Used in the next iteration */
118
119	subl	TERM_SIZE,%edi
120	decl	PARAM4
121	jns	L_accum_loop
122
123L_accum_done:
124	movl	PARAM1,%edi		/* accum */
125	movl	SUM_LS,%eax
126	addl	%eax,(%edi)
127	movl	SUM_MIDDLE,%eax
128	adcl	%eax,4(%edi)
129	movl	SUM_MS,%eax
130	adcl	%eax,8(%edi)
131
132	popl	%ebx
133	popl	%edi
134	popl	%esi
135	leave
136	RET
137SYM_FUNC_END(polynomial_Xsig)