diff options
author | jbj <devnull@localhost> | 2001-09-18 19:23:46 +0000 |
---|---|---|
committer | jbj <devnull@localhost> | 2001-09-18 19:23:46 +0000 |
commit | 78de87f74cc1a9cfffb9a198509f2e6697b8bca8 (patch) | |
tree | c2be7e2aeda8290b9108dba15750ee5af72f9d4f /beecrypt/gas/mp32opt.arm.S | |
parent | 38edc494525ccdf25f11ed2288378ba640928900 (diff) | |
download | librpm-tizen-78de87f74cc1a9cfffb9a198509f2e6697b8bca8.tar.gz librpm-tizen-78de87f74cc1a9cfffb9a198509f2e6697b8bca8.tar.bz2 librpm-tizen-78de87f74cc1a9cfffb9a198509f2e6697b8bca8.zip |
Initial revision
CVS patchset: 5051
CVS date: 2001/09/18 19:23:46
Diffstat (limited to 'beecrypt/gas/mp32opt.arm.S')
-rw-r--r-- | beecrypt/gas/mp32opt.arm.S | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/beecrypt/gas/mp32opt.arm.S b/beecrypt/gas/mp32opt.arm.S new file mode 100644 index 000000000..0f3916828 --- /dev/null +++ b/beecrypt/gas/mp32opt.arm.S @@ -0,0 +1,174 @@ +/* + * mp32opt.arm.S + * + * Assembler optimized multiprecision integer routines for ARM processors + * + * Compile target is GNU Assembler + * + * Copyright (c) 2001 Virtual Unlimited B.V. + * + * Author: Bob Deblier <bob@virtualunlimited.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "config.gas.h" + + .file "mp32opt.arm.S" + + .text + +/* ARM uses up to four registers for parameter passing */ + +#if 0 +C_FUNCTION_BEGIN(mp32addw) + /* r0 is xsize and must be at least one, r1 = xdata, r2 = y */ + stmfd sp!, {r4, lr} + add r1, r1, r0, asl #2 + mov r3, #0 +.Lmp32addw_loop: + ldr r4, [r1, #-4] + adds r4, r4, r2 + adc r2, r3, r3 + str r4, [r1, #-4]! + subs r0, r0, #1 + bne .Lmp32addw_loop + mov r0, r2 + ldmfd sp!, {r4, pc} +C_FUNCTION_END(mp32addw, .Lmp32addw_size) + + +C_FUNCTION_BEGIN(mp32subw) + /* r0 is xsize and must be at least one, r1 = xdata, r2 = y */ + stmfd sp!, {r4, lr} + add r1, r1, r0, asl #2 + mov r3, #0 +.Lmp32subw_loop: + ldr r4, [r1, #-4] + subs r4, r4, r2 + adc r2, r3, r3 + str r4, [r1, #-4]! + subs r0, r0, #1 + bne .Lmp32subw_loop + mov r0, r2 + ldmfd sp!, {r4, pc} +C_FUNCTION_END(mp32subw, .Lmp32subw_size) + + +C_FUNCTION_BEGIN(mp32add) + /* r0 is size, r1 = xdata, r2 = ydata */ + stmfd sp!, {r4, r5, lr} + /* copy cpsr to r5 and clear the carry bit */ + mrs r5, cpsr + bic r5, r5, #0x20000000 + /* adjust the addresses */ + add r1, r1, r0, asl #2 + add r2, r2, r0, asl #2 +.Lmp32add_loop: + /* restore the carry bit */ + msr cpsr_c, r5 + ldr r3, [r1, #-4]! + ldr r4, [r2, #-4]! + adcs r3, r3, r2 + str r3, [r1, #0] + /* save the carry bit */ + mrs r5, cpsr + subs r0, r0, #1 + bne .Lmp32add_loop + + /* restore the carry bit */ + msr cpsr_c, r5 + + /* set the result to the proper value */ + adc r0, r0, r0 + ldmfd sp!, {r4, r5, pc} +C_FUNCTION_END(mp32add, .Lmp32add_size) +#endif + + +C_FUNCTION_BEGIN(mp32setmul) + stmfd sp!, {r4, r5, lr} + /* adjust the addresses */ + add r1, r1, r0, asl #2 + add r2, r2, r0, asl #2 + /* r3 is the multiplicand; r4 load from memory, r5 is scratch, ip is carry */ + mov ip, #0 +.Lmp32setmul_loop: + ldr r4, [r2, #-4]! + mov r5, #0 + umlal ip, r5, r3, r4 + str ip, [r1, #-4]! + mov ip, r5 + subs r0, r0, #1 + bne .Lmp32setmul_loop + /* return carry */ + mov r0, ip + ldmfd sp!, {r4, r5, pc} +C_FUNCTION_END(mp32setmul, .Lmp32setmul_size) + + +C_FUNCTION_BEGIN(mp32addmul) + stmfd sp!, {r4, r5, r6, lr} + /* adjust the addresses */ + add r1, r1, r0, asl #2 + add r2, r2, r0, asl #2 + /* r3 is the multiplicand; r4 & r5 load from memory, r6 is scratch, ip is carry */ + mov ip, #0 +.Lmp32addmul_loop: + ldr r4, [r2, #-4]! + ldr r5, [r1, #-4] + mov r6, #0 + umlal ip, r6, r3, r4 + adds r5, r5, ip + adc ip, r6, #0 + str r5, [r1, #-4]! + subs r0, r0, #1 + bne .Lmp32addmul_loop + /* return carry */ + mov r0, ip + ldmfd sp!, {r4, r5, r6, pc} +C_FUNCTION_END(mp32addmul, .Lmp32addmul_size) + + +#if 0 +/* this routine needs fixing; it causes a core dump for some reason */ +/* unfortunately the system I test this on has no debugger */ +C_FUNCTION_BEGIN(mp32addsqrtrc) + stmfd sp!, {r4, r5, r6, lr} + /* adjust the addresses */ + add r1, r1, r0, asl #2 + add r2, r2, r0, asl #2 + /* r3 is a zero register, ip is the carry */ + mov r3, #0 + mov ip, #0 +.Lmp32addsqrtrc_loop: + ldr r4, [r2, #-4]! + mov r6, #0 + umlal ip, r6, r4, r4 + ldr r5, [r1, #-4] /* lo word */ + ldr r4, [r1, #-8] /* hi word */ + adds r5, r5, ip + adcs r4, r4, r6 + str r5, [r1, #-4] + str r4, [r1, #-8]! + adc ip, r3, #0 /* set carry */ + subs r0, r0, #1 + bne .Lmp32addsqrtrc_loop + /* return carry */ + mov r0, ip + ldmfd sp!, {r4, r5, r6, pc} +C_FUNCTION_END(mp32addsqrtrc, .Lmp32addsqrtrc_size) +#endif |