xref: /netbsd-src/external/lgpl3/gmp/dist/mpn/arm/logops_n.asm (revision f89f6560d453f5e37386cc7938c072d2f528b9fa)
1dnl  ARM mpn_and_n, mpn_andn_n. mpn_nand_n, etc.
2
3dnl  Contributed to the GNU project by Torbjorn Granlund.
4
5dnl  Copyright 1997, 2000, 2001, 2012 Free Software Foundation, Inc.
6
7dnl  This file is part of the GNU MP Library.
8
9dnl  The GNU MP Library is free software; you can redistribute it and/or modify
10dnl  it under the terms of the GNU Lesser General Public License as published
11dnl  by the Free Software Foundation; either version 3 of the License, or (at
12dnl  your option) any later version.
13
14dnl  The GNU MP Library is distributed in the hope that it will be useful, but
15dnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16dnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17dnl  License for more details.
18
19dnl  You should have received a copy of the GNU Lesser General Public License
20dnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
21
22include(`../config.m4')
23
24C            cycles/limb             cycles/limb
25C          and andn ior xor         nand iorn nior xnor
26C StrongARM	 ?			 ?
27C XScale	 ?			 ?
28C Cortex-A8	 ?			 ?
29C Cortex-A9	2.5-2.72		2.75-3
30C Cortex-A15	 ?			 ?
31
32C TODO
33C  * It seems that 2.25 c/l and 2.75 c/l is possible for A9.
34C  * Debug popping issue, see comment below.
35
36define(`rp', `r0')
37define(`up', `r1')
38define(`vp', `r2')
39define(`n',  `r3')
40
41define(`POSTOP')
42
43ifdef(`OPERATION_and_n',`
44  define(`func',    `mpn_and_n')
45  define(`LOGOP',   `and	$1, $2, $3')')
46ifdef(`OPERATION_andn_n',`
47  define(`func',    `mpn_andn_n')
48  define(`LOGOP',   `bic	$1, $2, $3')')
49ifdef(`OPERATION_nand_n',`
50  define(`func',    `mpn_nand_n')
51  define(`POSTOP',  `mvn	$1, $1')
52  define(`LOGOP',   `and	$1, $2, $3')')
53ifdef(`OPERATION_ior_n',`
54  define(`func',    `mpn_ior_n')
55  define(`LOGOP',   `orr	$1, $2, $3')')
56ifdef(`OPERATION_iorn_n',`
57  define(`func',    `mpn_iorn_n')
58  define(`POSTOP',  `mvn	$1, $1')
59  define(`LOGOP',   `bic	$1, $3, $2')')
60ifdef(`OPERATION_nior_n',`
61  define(`func',    `mpn_nior_n')
62  define(`POSTOP',  `mvn	$1, $1')
63  define(`LOGOP',   `orr	$1, $2, $3')')
64ifdef(`OPERATION_xor_n',`
65  define(`func',    `mpn_xor_n')
66  define(`LOGOP',   `eor	$1, $2, $3')')
67ifdef(`OPERATION_xnor_n',`
68  define(`func',    `mpn_xnor_n')
69  define(`POSTOP',  `mvn	$1, $1')
70  define(`LOGOP',   `eor	$1, $2, $3')')
71
72MULFUNC_PROLOGUE(mpn_and_n mpn_andn_n mpn_nand_n mpn_ior_n mpn_iorn_n mpn_nior_n mpn_xor_n mpn_xnor_n)
73
74ASM_START()
75PROLOGUE(func)
76	push	{ r8, r9, r10 }
77	tst	n, #1
78	beq	L(skip1)
79	ldr	r10, [vp], #4
80	ldr	r12, [up], #4
81	LOGOP(	r12, r12, r10)
82	POSTOP(	r12)
83	str	r12, [rp], #4
84L(skip1):
85	tst	n, #2
86	beq	L(skip2)
87	ldmia	vp!, { r10, r12 }
88	ldmia	up!, { r8, r9 }
89	LOGOP(	r8, r8, r10)
90	LOGOP(	r9, r9, r12)
91	POSTOP(	r8)
92	POSTOP(	r9)
93	stmia	rp!, { r8, r9 }
94L(skip2):
95	bics	n, n, #3
96	beq	L(rtn)
97	push	{ r4, r5, r6, r7 }
98
99	ldmia	vp!, { r8, r9, r10, r12 }
100	b	L(mid)
101
102L(top):	ldmia	vp!, { r8, r9, r10, r12 }
103	POSTOP(	r4)
104	POSTOP(	r5)
105	POSTOP(	r6)
106	POSTOP(	r7)
107	stmia	rp!, { r4, r5, r6, r7 }
108L(mid):	sub	n, n, #4
109	ldmia	up!, { r4, r5, r6, r7 }
110	teq	n, #0
111	LOGOP(	r4, r4, r8)
112	LOGOP(	r5, r5, r9)
113	LOGOP(	r6, r6, r10)
114	LOGOP(	r7, r7, r12)
115	bne	L(top)
116
117	POSTOP(	r4)
118	POSTOP(	r5)
119	POSTOP(	r6)
120	POSTOP(	r7)
121	stmia	rp!, { r4, r5, r6, r7 }
122
123	pop	{ r4, r5, r6, r7 }	C popping r8-r10 here strangely fails
124
125L(rtn):	pop	{ r8, r9, r10 }
126ifdef(`ARM_THUMB_MODE',
127`	bx	r14
128',`	mov	pc, r14
129')
130EPILOGUE()
131