1#ifndef __ASSEMBLER__
2# define __ASSEMBLER__ 1
3#endif
4#include "crypto/sparc_arch.h"
5
6#ifdef	__arch64__
7.register	%g2,#scratch
8.register	%g3,#scratch
9#endif
10
11.section	".text",#alloc,#execinstr
12.globl	bn_mul_mont_vis3
13.align	32
14bn_mul_mont_vis3:
15	add	%sp,	STACK_BIAS,	%g4	! real top of stack
16	sll	%o5,	2,	%o5	! size in bytes
17	add	%o5,	63,	%g5
18	andn	%g5,	63,	%g5	! buffer size rounded up to 64 bytes
19	add	%g5,	%g5,	%g1
20	add	%g5,	%g1,	%g1	! 3*buffer size
21	sub	%g4,	%g1,	%g1
22	andn	%g1,	63,	%g1	! align at 64 byte
23	sub	%g1,	STACK_FRAME,	%g1	! new top of stack
24	sub	%g1,	%g4,	%g1
25
26	save	%sp,	%g1,	%sp
27	ld	[%i4+0],	%l0	! pull n0[0..1] value
28	add	%sp, STACK_BIAS+STACK_FRAME, %l5
29	ld	[%i4+4],	%l1
30	add	%l5,	%g5,	%l7
31	ld	[%i2+0],	%l2	! m0=bp[0]
32	sllx	%l1,	32,	%g1
33	ld	[%i2+4],	%l3
34	or	%l0,	%g1,	%g1
35	add	%i2,	8,	%i2
36
37	ld	[%i1+0],	%l0	! ap[0]
38	sllx	%l3,	32,	%g2
39	ld	[%i1+4],	%l1
40	or	%l2,	%g2,	%g2
41
42	ld	[%i1+8],	%l2	! ap[1]
43	sllx	%l1,	32,	%o2
44	ld	[%i1+12],	%l3
45	or	%l0,	%o2,	%o2
46	add	%i1,	16,	%i1
47	stx	%o2,	[%l7]		! converted ap[0]
48
49	mulx	%o2,	%g2,	%g4	! ap[0]*bp[0]
50	.word	0x8bb282c2 !umulxhi	%o2,%g2,%g5
51
52	ld	[%i3+0],	%l0	! np[0]
53	sllx	%l3,	32,	%o2
54	ld	[%i3+4],	%l1
55	or	%l2,	%o2,	%o2
56
57	ld	[%i3+8],	%l2	! np[1]
58	sllx	%l1,	32,	%o4
59	ld	[%i3+12],	%l3
60	or	%l0, %o4,	%o4
61	add	%i3,	16,	%i3
62	stx	%o4,	[%l7+8]	! converted np[0]
63
64	mulx	%g4,	%g1,	%g3	! "tp[0]"*n0
65	stx	%o2,	[%l7+16]	! converted ap[1]
66
67	mulx	%o2,	%g2,	%o3	! ap[1]*bp[0]
68	.word	0x95b282c2 !umulxhi	%o2,%g2,%o2	! ahi=aj
69
70	mulx	%o4,	%g3,	%o0	! np[0]*m1
71	.word	0x93b302c3 !umulxhi	%o4,%g3,%o1
72
73	sllx	%l3,	32,	%o4
74	or	%l2,	%o4,	%o4
75	stx	%o4,	[%l7+24]	! converted np[1]
76	add	%l7,	32,	%l7
77
78	addcc	%g4,	%o0,	%o0
79	.word	0x93b00229 !addxc	%g0,%o1,%o1
80
81	mulx	%o4,	%g3,	%o5	! np[1]*m1
82	.word	0x99b302c3 !umulxhi	%o4,%g3,%o4	! nhi=nj
83
84	ba	.L1st
85	sub	%i5,	24,	%l4	! cnt=num-3
86
87.align	16
88.L1st:
89	ld	[%i1+0],	%l0	! ap[j]
90	addcc	%o3,	%g5,	%g4
91	ld	[%i1+4],	%l1
92	.word	0x8bb28220 !addxc	%o2,%g0,%g5
93
94	sllx	%l1,	32,	%o2
95	add	%i1,	8,	%i1
96	or	%l0,	%o2,	%o2
97	stx	%o2,	[%l7]		! converted ap[j]
98
99	ld	[%i3+0],	%l2	! np[j]
100	addcc	%o5,	%o1,	%o0
101	ld	[%i3+4],	%l3
102	.word	0x93b30220 !addxc	%o4,%g0,%o1	! nhi=nj
103
104	sllx	%l3,	32,	%o4
105	add	%i3,	8,	%i3
106	mulx	%o2,	%g2,	%o3	! ap[j]*bp[0]
107	or	%l2,	%o4,	%o4
108	.word	0x95b282c2 !umulxhi	%o2,%g2,%o2	! ahi=aj
109	stx	%o4,	[%l7+8]	! converted np[j]
110	add	%l7,	16,	%l7	! anp++
111
112	mulx	%o4,	%g3,	%o5	! np[j]*m1
113	addcc	%g4,	%o0,	%o0	! np[j]*m1+ap[j]*bp[0]
114	.word	0x99b302c3 !umulxhi	%o4,%g3,%o4	! nhi=nj
115	.word	0x93b00229 !addxc	%g0,%o1,%o1
116	stx	%o0,	[%l5]		! tp[j-1]
117	add	%l5,	8,	%l5	! tp++
118
119	brnz,pt	%l4,	.L1st
120	sub	%l4,	8,	%l4	! j--
121!.L1st
122	addcc	%o3,	%g5,	%g4
123	.word	0x8bb28220 !addxc	%o2,%g0,%g5	! ahi=aj
124
125	addcc	%o5,	%o1,	%o0
126	.word	0x93b30220 !addxc	%o4,%g0,%o1
127	addcc	%g4,	%o0,	%o0	! np[j]*m1+ap[j]*bp[0]
128	.word	0x93b00229 !addxc	%g0,%o1,%o1
129	stx	%o0,	[%l5]		! tp[j-1]
130	add	%l5,	8,	%l5
131
132	addcc	%g5,	%o1,	%o1
133	.word	0xa1b00220 !addxc	%g0,%g0,%l0	! upmost overflow bit
134	stx	%o1,	[%l5]
135	add	%l5,	8,	%l5
136
137	ba	.Louter
138	sub	%i5,	16,	%l1	! i=num-2
139
140.align	16
141.Louter:
142	ld	[%i2+0],	%l2	! m0=bp[i]
143	ld	[%i2+4],	%l3
144
145	sub	%l7,	%i5,	%l7	! rewind
146	sub	%l5,	%i5,	%l5
147	sub	%l7,	%i5,	%l7
148
149	add	%i2,	8,	%i2
150	sllx	%l3,	32,	%g2
151	ldx	[%l7+0],	%o2	! ap[0]
152	or	%l2,	%g2,	%g2
153	ldx	[%l7+8],	%o4	! np[0]
154
155	mulx	%o2,	%g2,	%g4	! ap[0]*bp[i]
156	ldx	[%l5],		%o7	! tp[0]
157	.word	0x8bb282c2 !umulxhi	%o2,%g2,%g5
158	ldx	[%l7+16],	%o2	! ap[1]
159	addcc	%g4,	%o7,	%g4	! ap[0]*bp[i]+tp[0]
160	mulx	%o2,	%g2,	%o3	! ap[1]*bp[i]
161	.word	0x8bb00225 !addxc	%g0,%g5,%g5
162	mulx	%g4,	%g1,	%g3	! tp[0]*n0
163	.word	0x95b282c2 !umulxhi	%o2,%g2,%o2	! ahi=aj
164	mulx	%o4,	%g3,	%o0	! np[0]*m1
165	.word	0x93b302c3 !umulxhi	%o4,%g3,%o1
166	ldx	[%l7+24],	%o4	! np[1]
167	add	%l7,	32,	%l7
168	addcc	%o0,	%g4,	%o0
169	mulx	%o4,	%g3,	%o5	! np[1]*m1
170	.word	0x93b00229 !addxc	%g0,%o1,%o1
171	.word	0x99b302c3 !umulxhi	%o4,%g3,%o4	! nhi=nj
172
173	ba	.Linner
174	sub	%i5,	24,	%l4	! cnt=num-3
175.align	16
176.Linner:
177	addcc	%o3,	%g5,	%g4
178	ldx	[%l5+8],	%o7	! tp[j]
179	.word	0x8bb28220 !addxc	%o2,%g0,%g5	! ahi=aj
180	ldx	[%l7+0],	%o2	! ap[j]
181	addcc	%o5,	%o1,	%o0
182	mulx	%o2,	%g2,	%o3	! ap[j]*bp[i]
183	.word	0x93b30220 !addxc	%o4,%g0,%o1	! nhi=nj
184	ldx	[%l7+8],	%o4	! np[j]
185	add	%l7,	16,	%l7
186	.word	0x95b282c2 !umulxhi	%o2,%g2,%o2	! ahi=aj
187	addcc	%g4,	%o7,	%g4	! ap[j]*bp[i]+tp[j]
188	mulx	%o4,	%g3,	%o5	! np[j]*m1
189	.word	0x8bb00225 !addxc	%g0,%g5,%g5
190	.word	0x99b302c3 !umulxhi	%o4,%g3,%o4	! nhi=nj
191	addcc	%o0,	%g4,	%o0	! np[j]*m1+ap[j]*bp[i]+tp[j]
192	.word	0x93b00229 !addxc	%g0,%o1,%o1
193	stx	%o0,	[%l5]		! tp[j-1]
194	add	%l5,	8,	%l5
195	brnz,pt	%l4,	.Linner
196	sub	%l4,	8,	%l4
197!.Linner
198	ldx	[%l5+8],	%o7	! tp[j]
199	addcc	%o3,	%g5,	%g4
200	.word	0x8bb28220 !addxc	%o2,%g0,%g5	! ahi=aj
201	addcc	%g4,	%o7,	%g4	! ap[j]*bp[i]+tp[j]
202	.word	0x8bb00225 !addxc	%g0,%g5,%g5
203
204	addcc	%o5,	%o1,	%o0
205	.word	0x93b30220 !addxc	%o4,%g0,%o1	! nhi=nj
206	addcc	%o0,	%g4,	%o0	! np[j]*m1+ap[j]*bp[i]+tp[j]
207	.word	0x93b00229 !addxc	%g0,%o1,%o1
208	stx	%o0,	[%l5]		! tp[j-1]
209
210	subcc	%g0,	%l0,	%g0	! move upmost overflow to CCR.xcc
211	.word	0x93b24265 !addxccc	%o1,%g5,%o1
212	.word	0xa1b00220 !addxc	%g0,%g0,%l0
213	stx	%o1,	[%l5+8]
214	add	%l5,	16,	%l5
215
216	brnz,pt	%l1,	.Louter
217	sub	%l1,	8,	%l1
218
219	sub	%l7,	%i5,	%l7	! rewind
220	sub	%l5,	%i5,	%l5
221	sub	%l7,	%i5,	%l7
222	ba	.Lsub
223	subcc	%i5,	8,	%l4	! cnt=num-1 and clear CCR.xcc
224
225.align	16
226.Lsub:
227	ldx	[%l5],		%o7
228	add	%l5,	8,	%l5
229	ldx	[%l7+8],	%o4
230	add	%l7,	16,	%l7
231	subccc	%o7,	%o4,	%l2	! tp[j]-np[j]
232	srlx	%o7,	32,	%o7
233	srlx	%o4,	32,	%o4
234	subccc	%o7,	%o4,	%l3
235	add	%i0,	8,	%i0
236	st	%l2,	[%i0-4]		! reverse order
237	st	%l3,	[%i0-8]
238	brnz,pt	%l4,	.Lsub
239	sub	%l4,	8,	%l4
240
241	sub	%l7,	%i5,	%l7	! rewind
242	sub	%l5,	%i5,	%l5
243	sub	%l7,	%i5,	%l7
244	sub	%i0,	%i5,	%i0
245
246	subccc	%l0,	%g0,	%l0	! handle upmost overflow bit
247	ba	.Lcopy
248	sub	%i5,	8,	%l4
249
250.align	16
251.Lcopy:					! conditional copy
252	ld	[%l5+0],	%l0
253	ld	[%l5+4],	%l1
254	ld	[%i0+0],	%l2
255	ld	[%i0+4],	%l3
256	stx	%g0,	[%l5]		! zap
257	add	%l5,	8,	%l5
258	stx	%g0,	[%l7]		! zap
259	stx	%g0,	[%l7+8]
260	add	%l7,	16,	%l7
261	movcs	%icc,	%l0,	%l2
262	movcs	%icc,	%l1,	%l3
263	st	%l3,	[%i0+0]		! flip order
264	st	%l2,	[%i0+4]
265	add	%i0,	8,	%i0
266	brnz	%l4,	.Lcopy
267	sub	%l4,	8,	%l4
268
269	mov	1,	%o0
270	ret
271	restore
272.type	bn_mul_mont_vis3, #function
273.size	bn_mul_mont_vis3, .-bn_mul_mont_vis3
274.asciz  "Montgomery Multiplication for SPARCv9 VIS3, CRYPTOGAMS by <appro@openssl.org>"
275.align	4
276