#include "sysdep.h"
#include "asm-syntax.h"
#include "bp-sym.h"
#include "bp-asm.h"
#define PARMS LINKAGE+16
#define RES PARMS
#define S RES+PTR_SIZE
#define SIZE S+PTR_SIZE
#define CNT SIZE+4
.text
ENTRY (BP_SYM (__mpn_lshift))
ENTER
pushl %edi
pushl %esi
pushl %ebp
pushl %ebx
movl RES(%esp),%edi
movl S(%esp),%esi
movl SIZE(%esp),%ebx
movl CNT(%esp),%ecx
#if __BOUNDED_POINTERS__
shll $2, %ebx
CHECK_BOUNDS_BOTH_WIDE (%edi, RES(%esp), %ebx)
CHECK_BOUNDS_BOTH_WIDE (%esi, S(%esp), %ebx)
shrl $2, %ebx
#endif
cmp $1,%ecx
jne L(normal)
leal 4(%esi),%eax
cmpl %edi,%eax
jnc L(special)
leal (%esi,%ebx,4),%eax
cmpl %eax,%edi
jnc L(special)
L(normal):
leal -4(%edi,%ebx,4),%edi
leal -4(%esi,%ebx,4),%esi
movl (%esi),%edx
subl $4,%esi
xorl %eax,%eax
shldl %cl,%edx,%eax
pushl %eax
decl %ebx
pushl %ebx
shrl $3,%ebx
jz L(end)
movl (%edi),%eax
ALIGN (2)
L(oop): movl -28(%edi),%eax
movl %edx,%ebp
movl (%esi),%eax
movl -4(%esi),%edx
shldl %cl,%eax,%ebp
shldl %cl,%edx,%eax
movl %ebp,(%edi)
movl %eax,-4(%edi)
movl -8(%esi),%ebp
movl -12(%esi),%eax
shldl %cl,%ebp,%edx
shldl %cl,%eax,%ebp
movl %edx,-8(%edi)
movl %ebp,-12(%edi)
movl -16(%esi),%edx
movl -20(%esi),%ebp
shldl %cl,%edx,%eax
shldl %cl,%ebp,%edx
movl %eax,-16(%edi)
movl %edx,-20(%edi)
movl -24(%esi),%eax
movl -28(%esi),%edx
shldl %cl,%eax,%ebp
shldl %cl,%edx,%eax
movl %ebp,-24(%edi)
movl %eax,-28(%edi)
subl $32,%esi
subl $32,%edi
decl %ebx
jnz L(oop)
L(end): popl %ebx
andl $7,%ebx
jz L(end2)
L(oop2):
movl (%esi),%eax
shldl %cl,%eax,%edx
movl %edx,(%edi)
movl %eax,%edx
subl $4,%esi
subl $4,%edi
decl %ebx
jnz L(oop2)
L(end2):
shll %cl,%edx
movl %edx,(%edi)
popl %eax
popl %ebx
popl %ebp
popl %esi
popl %edi
LEAVE
ret
L(special):
movl (%esi),%edx
addl $4,%esi
decl %ebx
pushl %ebx
shrl $3,%ebx
addl %edx,%edx
incl %ebx
decl %ebx
jz L(Lend)
movl (%edi),%eax
ALIGN (2)
L(Loop):
movl 28(%edi),%eax
movl %edx,%ebp
movl (%esi),%eax
movl 4(%esi),%edx
adcl %eax,%eax
movl %ebp,(%edi)
adcl %edx,%edx
movl %eax,4(%edi)
movl 8(%esi),%ebp
movl 12(%esi),%eax
adcl %ebp,%ebp
movl %edx,8(%edi)
adcl %eax,%eax
movl %ebp,12(%edi)
movl 16(%esi),%edx
movl 20(%esi),%ebp
adcl %edx,%edx
movl %eax,16(%edi)
adcl %ebp,%ebp
movl %edx,20(%edi)
movl 24(%esi),%eax
movl 28(%esi),%edx
adcl %eax,%eax
movl %ebp,24(%edi)
adcl %edx,%edx
movl %eax,28(%edi)
leal 32(%esi),%esi
leal 32(%edi),%edi
decl %ebx
jnz L(Loop)
L(Lend):
popl %ebx
sbbl %eax,%eax
andl $7,%ebx
jz L(Lend2)
addl %eax,%eax
L(Loop2):
movl %edx,%ebp
movl (%esi),%edx
adcl %edx,%edx
movl %ebp,(%edi)
leal 4(%esi),%esi
leal 4(%edi),%edi
decl %ebx
jnz L(Loop2)
jmp L(L1)
L(Lend2):
addl %eax,%eax
L(L1): movl %edx,(%edi)
sbbl %eax,%eax
negl %eax
popl %ebx
popl %ebp
popl %esi
popl %edi
LEAVE
ret
END (BP_SYM (__mpn_lshift))