forked from Minki/linux
bd6be579a7
Functions in math-emu are annotated as ENTRY() symbols, but their ends are not annotated at all. But these are standard functions called from C, with proper stack register update etc. Omitting the ends means: * the annotations are not paired and we cannot deal with such functions e.g. in objtool * the symbols are not marked as functions in the object file * there are no sizes of the functions in the object file So fix this by adding ENDPROC() to each such case in math-emu. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20170824080624.7768-1-jslaby@suse.cz Signed-off-by: Ingo Molnar <mingo@kernel.org>
137 lines
3.9 KiB
ArmAsm
137 lines
3.9 KiB
ArmAsm
/*---------------------------------------------------------------------------+
|
|
| polynomial_Xsig.S |
|
|
| |
|
|
| Fixed point arithmetic polynomial evaluation. |
|
|
| |
|
|
| Copyright (C) 1992,1993,1994,1995 |
|
|
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
|
|
| Australia. E-mail billm@jacobi.maths.monash.edu.au |
|
|
| |
|
|
| Call from C as: |
|
|
| void polynomial_Xsig(Xsig *accum, unsigned long long x, |
|
|
| unsigned long long terms[], int n) |
|
|
| |
|
|
| Computes: |
|
|
| terms[0] + (terms[1] + (terms[2] + ... + (terms[n-1]*x)*x)*x)*x) ... )*x |
|
|
| and adds the result to the 12 byte Xsig. |
|
|
| The terms[] are each 8 bytes, but all computation is performed to 12 byte |
|
|
| precision. |
|
|
| |
|
|
| This function must be used carefully: most overflow of intermediate |
|
|
| results is controlled, but overflow of the result is not. |
|
|
| |
|
|
+---------------------------------------------------------------------------*/
|
|
.file "polynomial_Xsig.S"
|
|
|
|
#include "fpu_emu.h"
|
|
|
|
|
|
#define TERM_SIZE $8
|
|
#define SUM_MS -20(%ebp) /* sum ms long */
|
|
#define SUM_MIDDLE -24(%ebp) /* sum middle long */
|
|
#define SUM_LS -28(%ebp) /* sum ls long */
|
|
#define ACCUM_MS -4(%ebp) /* accum ms long */
|
|
#define ACCUM_MIDDLE -8(%ebp) /* accum middle long */
|
|
#define ACCUM_LS -12(%ebp) /* accum ls long */
|
|
#define OVERFLOWED -16(%ebp) /* addition overflow flag */
|
|
|
|
.text
|
|
ENTRY(polynomial_Xsig)
|
|
pushl %ebp
|
|
movl %esp,%ebp
|
|
subl $32,%esp
|
|
pushl %esi
|
|
pushl %edi
|
|
pushl %ebx
|
|
|
|
movl PARAM2,%esi /* x */
|
|
movl PARAM3,%edi /* terms */
|
|
|
|
movl TERM_SIZE,%eax
|
|
mull PARAM4 /* n */
|
|
addl %eax,%edi
|
|
|
|
movl 4(%edi),%edx /* terms[n] */
|
|
movl %edx,SUM_MS
|
|
movl (%edi),%edx /* terms[n] */
|
|
movl %edx,SUM_MIDDLE
|
|
xor %eax,%eax
|
|
movl %eax,SUM_LS
|
|
movb %al,OVERFLOWED
|
|
|
|
subl TERM_SIZE,%edi
|
|
decl PARAM4
|
|
js L_accum_done
|
|
|
|
L_accum_loop:
|
|
xor %eax,%eax
|
|
movl %eax,ACCUM_MS
|
|
movl %eax,ACCUM_MIDDLE
|
|
|
|
movl SUM_MIDDLE,%eax
|
|
mull (%esi) /* x ls long */
|
|
movl %edx,ACCUM_LS
|
|
|
|
movl SUM_MIDDLE,%eax
|
|
mull 4(%esi) /* x ms long */
|
|
addl %eax,ACCUM_LS
|
|
adcl %edx,ACCUM_MIDDLE
|
|
adcl $0,ACCUM_MS
|
|
|
|
movl SUM_MS,%eax
|
|
mull (%esi) /* x ls long */
|
|
addl %eax,ACCUM_LS
|
|
adcl %edx,ACCUM_MIDDLE
|
|
adcl $0,ACCUM_MS
|
|
|
|
movl SUM_MS,%eax
|
|
mull 4(%esi) /* x ms long */
|
|
addl %eax,ACCUM_MIDDLE
|
|
adcl %edx,ACCUM_MS
|
|
|
|
testb $0xff,OVERFLOWED
|
|
jz L_no_overflow
|
|
|
|
movl (%esi),%eax
|
|
addl %eax,ACCUM_MIDDLE
|
|
movl 4(%esi),%eax
|
|
adcl %eax,ACCUM_MS /* This could overflow too */
|
|
|
|
L_no_overflow:
|
|
|
|
/*
|
|
* Now put the sum of next term and the accumulator
|
|
* into the sum register
|
|
*/
|
|
movl ACCUM_LS,%eax
|
|
addl (%edi),%eax /* term ls long */
|
|
movl %eax,SUM_LS
|
|
movl ACCUM_MIDDLE,%eax
|
|
adcl (%edi),%eax /* term ls long */
|
|
movl %eax,SUM_MIDDLE
|
|
movl ACCUM_MS,%eax
|
|
adcl 4(%edi),%eax /* term ms long */
|
|
movl %eax,SUM_MS
|
|
sbbb %al,%al
|
|
movb %al,OVERFLOWED /* Used in the next iteration */
|
|
|
|
subl TERM_SIZE,%edi
|
|
decl PARAM4
|
|
jns L_accum_loop
|
|
|
|
L_accum_done:
|
|
movl PARAM1,%edi /* accum */
|
|
movl SUM_LS,%eax
|
|
addl %eax,(%edi)
|
|
movl SUM_MIDDLE,%eax
|
|
adcl %eax,4(%edi)
|
|
movl SUM_MS,%eax
|
|
adcl %eax,8(%edi)
|
|
|
|
popl %ebx
|
|
popl %edi
|
|
popl %esi
|
|
leave
|
|
ret
|
|
ENDPROC(polynomial_Xsig)
|