des/des_locl.h: clean up unused/irrelevant macros.
[openssl.git] / crypto / bn / asm / pa-risc2.s
1 ; Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
2 ;
3 ; Licensed under the OpenSSL license (the "License").  You may not use
4 ; this file except in compliance with the License.  You can obtain a copy
5 ; in the file LICENSE in the source distribution or at
6 ; https://www.openssl.org/source/license.html
7 ;
8 ; PA-RISC 2.0 implementation of bn_asm code, based on the
9 ; 64-bit version of the code.  This code is effectively the
10 ; same as the 64-bit version except the register model is
11 ; slightly different given all values must be 32-bit between
12 ; function calls.  Thus the 64-bit return values are returned
13 ; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit
14 ;
15 ;
16 ; This code is approximately 2x faster than the C version
17 ; for RSA/DSA.
18 ;
19 ; See http://devresource.hp.com/  for more details on the PA-RISC
20 ; architecture.  Also see the book "PA-RISC 2.0 Architecture"
21 ; by Gerry Kane for information on the instruction set architecture.
22 ;
23 ; Code written by Chris Ruemmler (with some help from the HP C
24 ; compiler).
25 ;
26 ; The code compiles with HP's assembler
27 ;
28
29         .level  2.0N
30         .space  $TEXT$
31         .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
32
33 ;
34 ; Global Register definitions used for the routines.
35 ;
36 ; Some information about HP's runtime architecture for 32-bits.
37 ;
38 ; "Caller save" means the calling function must save the register
39 ; if it wants the register to be preserved.
40 ; "Callee save" means if a function uses the register, it must save
41 ; the value before using it.
42 ;
43 ; For the floating point registers 
44 ;
45 ;    "caller save" registers: fr4-fr11, fr22-fr31
46 ;    "callee save" registers: fr12-fr21
47 ;    "special" registers: fr0-fr3 (status and exception registers)
48 ;
49 ; For the integer registers
50 ;     value zero             :  r0
51 ;     "caller save" registers: r1,r19-r26
52 ;     "callee save" registers: r3-r18
53 ;     return register        :  r2  (rp)
54 ;     return values          ; r28,r29  (ret0,ret1)
55 ;     Stack pointer          ; r30  (sp) 
56 ;     millicode return ptr   ; r31  (also a caller save register)
57
58
59 ;
60 ; Arguments to the routines
61 ;
62 r_ptr       .reg %r26
63 a_ptr       .reg %r25
64 b_ptr       .reg %r24
65 num         .reg %r24
66 n           .reg %r23
67
68 ;
69 ; Note that the "w" argument for bn_mul_add_words and bn_mul_words
70 ; is passed on the stack at a delta of -56 from the top of stack
71 ; as the routine is entered.
72 ;
73
74 ;
75 ; Globals used in some routines
76 ;
77
78 top_overflow .reg %r23
79 high_mask    .reg %r22    ; value 0xffffffff80000000L
80
81
82 ;------------------------------------------------------------------------------
83 ;
84 ; bn_mul_add_words
85 ;
86 ;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, 
87 ;                                                               int num, BN_ULONG w)
88 ;
89 ; arg0 = r_ptr
90 ; arg1 = a_ptr
91 ; arg3 = num
92 ; -56(sp) =  w
93 ;
94 ; Local register definitions
95 ;
96
97 fm1          .reg %fr22
98 fm           .reg %fr23
99 ht_temp      .reg %fr24
100 ht_temp_1    .reg %fr25
101 lt_temp      .reg %fr26
102 lt_temp_1    .reg %fr27
103 fm1_1        .reg %fr28
104 fm_1         .reg %fr29
105
106 fw_h         .reg %fr7L
107 fw_l         .reg %fr7R
108 fw           .reg %fr7
109
110 fht_0        .reg %fr8L
111 flt_0        .reg %fr8R
112 t_float_0    .reg %fr8
113
114 fht_1        .reg %fr9L
115 flt_1        .reg %fr9R
116 t_float_1    .reg %fr9
117
118 tmp_0        .reg %r31
119 tmp_1        .reg %r21
120 m_0          .reg %r20 
121 m_1          .reg %r19 
122 ht_0         .reg %r1  
123 ht_1         .reg %r3
124 lt_0         .reg %r4
125 lt_1         .reg %r5
126 m1_0         .reg %r6 
127 m1_1         .reg %r7 
128 rp_val       .reg %r8
129 rp_val_1     .reg %r9
130
131 bn_mul_add_words
132         .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
133         .proc
134         .callinfo frame=128
135     .entry
136         .align 64
137
138     STD     %r3,0(%sp)          ; save r3  
139     STD     %r4,8(%sp)          ; save r4  
140         NOP                         ; Needed to make the loop 16-byte aligned
141         NOP                         ; needed to make the loop 16-byte aligned
142
143     STD     %r5,16(%sp)         ; save r5  
144         NOP
145     STD     %r6,24(%sp)         ; save r6  
146     STD     %r7,32(%sp)         ; save r7  
147
148     STD     %r8,40(%sp)         ; save r8  
149     STD     %r9,48(%sp)         ; save r9  
150     COPY    %r0,%ret1           ; return 0 by default
151     DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
152
153     CMPIB,>= 0,num,bn_mul_add_words_exit  ; if (num <= 0) then exit
154         LDO     128(%sp),%sp        ; bump stack
155
156         ;
157         ; The loop is unrolled twice, so if there is only 1 number
158     ; then go straight to the cleanup code.
159         ;
160         CMPIB,= 1,num,bn_mul_add_words_single_top
161         FLDD    -184(%sp),fw        ; (-56-128) load up w into fw (fw_h/fw_l)
162
163         ;
164         ; This loop is unrolled 2 times (64-byte aligned as well)
165         ;
166         ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
167     ; two 32-bit mutiplies can be issued per cycle.
168     ; 
169 bn_mul_add_words_unroll2
170
171     FLDD    0(a_ptr),t_float_0       ; load up 64-bit value (fr8L) ht(L)/lt(R)
172     FLDD    8(a_ptr),t_float_1       ; load up 64-bit value (fr8L) ht(L)/lt(R)
173     LDD     0(r_ptr),rp_val          ; rp[0]
174     LDD     8(r_ptr),rp_val_1        ; rp[1]
175
176     XMPYU   fht_0,fw_l,fm1           ; m1[0] = fht_0*fw_l
177     XMPYU   fht_1,fw_l,fm1_1         ; m1[1] = fht_1*fw_l
178     FSTD    fm1,-16(%sp)             ; -16(sp) = m1[0]
179     FSTD    fm1_1,-48(%sp)           ; -48(sp) = m1[1]
180
181     XMPYU   flt_0,fw_h,fm            ; m[0] = flt_0*fw_h
182     XMPYU   flt_1,fw_h,fm_1          ; m[1] = flt_1*fw_h
183     FSTD    fm,-8(%sp)               ; -8(sp) = m[0]
184     FSTD    fm_1,-40(%sp)            ; -40(sp) = m[1]
185
186     XMPYU   fht_0,fw_h,ht_temp       ; ht_temp   = fht_0*fw_h
187     XMPYU   fht_1,fw_h,ht_temp_1     ; ht_temp_1 = fht_1*fw_h
188     FSTD    ht_temp,-24(%sp)         ; -24(sp)   = ht_temp
189     FSTD    ht_temp_1,-56(%sp)       ; -56(sp)   = ht_temp_1
190
191     XMPYU   flt_0,fw_l,lt_temp       ; lt_temp = lt*fw_l
192     XMPYU   flt_1,fw_l,lt_temp_1     ; lt_temp = lt*fw_l
193     FSTD    lt_temp,-32(%sp)         ; -32(sp) = lt_temp 
194     FSTD    lt_temp_1,-64(%sp)       ; -64(sp) = lt_temp_1 
195
196     LDD     -8(%sp),m_0              ; m[0] 
197     LDD     -40(%sp),m_1             ; m[1]
198     LDD     -16(%sp),m1_0            ; m1[0]
199     LDD     -48(%sp),m1_1            ; m1[1]
200
201     LDD     -24(%sp),ht_0            ; ht[0]
202     LDD     -56(%sp),ht_1            ; ht[1]
203     ADD,L   m1_0,m_0,tmp_0           ; tmp_0 = m[0] + m1[0]; 
204     ADD,L   m1_1,m_1,tmp_1           ; tmp_1 = m[1] + m1[1]; 
205
206     LDD     -32(%sp),lt_0            
207     LDD     -64(%sp),lt_1            
208     CMPCLR,*>>= tmp_0,m1_0, %r0      ; if (m[0] < m1[0])
209     ADD,L   ht_0,top_overflow,ht_0   ; ht[0] += (1<<32)
210
211     CMPCLR,*>>= tmp_1,m1_1,%r0       ; if (m[1] < m1[1])
212     ADD,L   ht_1,top_overflow,ht_1   ; ht[1] += (1<<32)
213     EXTRD,U tmp_0,31,32,m_0          ; m[0]>>32  
214     DEPD,Z  tmp_0,31,32,m1_0         ; m1[0] = m[0]<<32 
215
216     EXTRD,U tmp_1,31,32,m_1          ; m[1]>>32  
217     DEPD,Z  tmp_1,31,32,m1_1         ; m1[1] = m[1]<<32 
218     ADD,L   ht_0,m_0,ht_0            ; ht[0]+= (m[0]>>32)
219     ADD,L   ht_1,m_1,ht_1            ; ht[1]+= (m[1]>>32)
220
221     ADD     lt_0,m1_0,lt_0           ; lt[0] = lt[0]+m1[0];
222         ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
223     ADD     lt_1,m1_1,lt_1           ; lt[1] = lt[1]+m1[1];
224     ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
225
226     ADD    %ret1,lt_0,lt_0           ; lt[0] = lt[0] + c;
227         ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
228     ADD     lt_0,rp_val,lt_0         ; lt[0] = lt[0]+rp[0]
229     ADD,DC  ht_0,%r0,ht_0            ; ht[0]++
230
231         LDO    -2(num),num               ; num = num - 2;
232     ADD     ht_0,lt_1,lt_1           ; lt[1] = lt[1] + ht_0 (c);
233     ADD,DC  ht_1,%r0,ht_1            ; ht[1]++
234     STD     lt_0,0(r_ptr)            ; rp[0] = lt[0]
235
236     ADD     lt_1,rp_val_1,lt_1       ; lt[1] = lt[1]+rp[1]
237     ADD,DC  ht_1,%r0,%ret1           ; ht[1]++
238     LDO     16(a_ptr),a_ptr          ; a_ptr += 2
239
240     STD     lt_1,8(r_ptr)            ; rp[1] = lt[1]
241         CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
242     LDO     16(r_ptr),r_ptr          ; r_ptr += 2
243
244     CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
245
246         ;
247         ; Top of loop aligned on 64-byte boundary
248         ;
249 bn_mul_add_words_single_top
250     FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
251     LDD     0(r_ptr),rp_val           ; rp[0]
252     LDO     8(a_ptr),a_ptr            ; a_ptr++
253     XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
254     FSTD    fm1,-16(%sp)              ; -16(sp) = m1
255     XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
256     FSTD    fm,-8(%sp)                ; -8(sp) = m
257     XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
258     FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
259     XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
260     FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
261
262     LDD     -8(%sp),m_0               
263     LDD    -16(%sp),m1_0              ; m1 = temp1 
264     ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
265     LDD     -24(%sp),ht_0             
266     LDD     -32(%sp),lt_0             
267
268     CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
269     ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
270
271     EXTRD,U tmp_0,31,32,m_0           ; m>>32  
272     DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
273
274     ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
275     ADD     lt_0,m1_0,tmp_0           ; tmp_0 = lt+m1;
276     ADD,DC  ht_0,%r0,ht_0             ; ht++
277     ADD     %ret1,tmp_0,lt_0          ; lt = lt + c;
278     ADD,DC  ht_0,%r0,ht_0             ; ht++
279     ADD     lt_0,rp_val,lt_0          ; lt = lt+rp[0]
280     ADD,DC  ht_0,%r0,%ret1            ; ht++
281     STD     lt_0,0(r_ptr)             ; rp[0] = lt
282
283 bn_mul_add_words_exit
284     .EXIT
285         
286     EXTRD,U %ret1,31,32,%ret0         ; for 32-bit, return in ret0/ret1
287     LDD     -80(%sp),%r9              ; restore r9  
288     LDD     -88(%sp),%r8              ; restore r8  
289     LDD     -96(%sp),%r7              ; restore r7  
290     LDD     -104(%sp),%r6             ; restore r6  
291     LDD     -112(%sp),%r5             ; restore r5  
292     LDD     -120(%sp),%r4             ; restore r4  
293     BVE     (%rp)
294     LDD,MB  -128(%sp),%r3             ; restore r3
295         .PROCEND        ;in=23,24,25,26,29;out=28;
296
297 ;----------------------------------------------------------------------------
298 ;
299 ;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
300 ;
301 ; arg0 = rp
302 ; arg1 = ap
303 ; arg3 = num
304 ; w on stack at -56(sp)
305
306 bn_mul_words
307         .proc
308         .callinfo frame=128
309     .entry
310         .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
311         .align 64
312
313     STD     %r3,0(%sp)          ; save r3  
314     STD     %r4,8(%sp)          ; save r4  
315         NOP
316     STD     %r5,16(%sp)         ; save r5  
317
318     STD     %r6,24(%sp)         ; save r6  
319     STD     %r7,32(%sp)         ; save r7  
320     COPY    %r0,%ret1           ; return 0 by default
321     DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32    
322
323     CMPIB,>= 0,num,bn_mul_words_exit
324         LDO     128(%sp),%sp    ; bump stack
325
326         ;
327         ; See if only 1 word to do, thus just do cleanup
328         ;
329         CMPIB,= 1,num,bn_mul_words_single_top
330         FLDD    -184(%sp),fw        ; (-56-128) load up w into fw (fw_h/fw_l)
331
332         ;
333         ; This loop is unrolled 2 times (64-byte aligned as well)
334         ;
335         ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
336     ; two 32-bit mutiplies can be issued per cycle.
337     ; 
338 bn_mul_words_unroll2
339
340     FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
341     FLDD    8(a_ptr),t_float_1        ; load up 64-bit value (fr8L) ht(L)/lt(R)
342     XMPYU   fht_0,fw_l,fm1            ; m1[0] = fht_0*fw_l
343     XMPYU   fht_1,fw_l,fm1_1          ; m1[1] = ht*fw_l
344
345     FSTD    fm1,-16(%sp)              ; -16(sp) = m1
346     FSTD    fm1_1,-48(%sp)            ; -48(sp) = m1
347     XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
348     XMPYU   flt_1,fw_h,fm_1           ; m = lt*fw_h
349
350     FSTD    fm,-8(%sp)                ; -8(sp) = m
351     FSTD    fm_1,-40(%sp)             ; -40(sp) = m
352     XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = fht_0*fw_h
353     XMPYU   fht_1,fw_h,ht_temp_1      ; ht_temp = ht*fw_h
354
355     FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
356     FSTD    ht_temp_1,-56(%sp)        ; -56(sp) = ht
357     XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
358     XMPYU   flt_1,fw_l,lt_temp_1      ; lt_temp = lt*fw_l
359
360     FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
361     FSTD    lt_temp_1,-64(%sp)        ; -64(sp) = lt 
362     LDD     -8(%sp),m_0               
363     LDD     -40(%sp),m_1              
364
365     LDD    -16(%sp),m1_0              
366     LDD    -48(%sp),m1_1              
367     LDD     -24(%sp),ht_0             
368     LDD     -56(%sp),ht_1             
369
370     ADD,L   m1_0,m_0,tmp_0            ; tmp_0 = m + m1; 
371     ADD,L   m1_1,m_1,tmp_1            ; tmp_1 = m + m1; 
372     LDD     -32(%sp),lt_0             
373     LDD     -64(%sp),lt_1             
374
375     CMPCLR,*>>= tmp_0,m1_0, %r0       ; if (m < m1)
376     ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
377     CMPCLR,*>>= tmp_1,m1_1,%r0        ; if (m < m1)
378     ADD,L   ht_1,top_overflow,ht_1    ; ht += (1<<32)
379
380     EXTRD,U tmp_0,31,32,m_0           ; m>>32  
381     DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
382     EXTRD,U tmp_1,31,32,m_1           ; m>>32  
383     DEPD,Z  tmp_1,31,32,m1_1          ; m1 = m<<32 
384
385     ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
386     ADD,L   ht_1,m_1,ht_1             ; ht+= (m>>32)
387     ADD     lt_0,m1_0,lt_0            ; lt = lt+m1;
388         ADD,DC  ht_0,%r0,ht_0             ; ht++
389
390     ADD     lt_1,m1_1,lt_1            ; lt = lt+m1;
391     ADD,DC  ht_1,%r0,ht_1             ; ht++
392     ADD    %ret1,lt_0,lt_0            ; lt = lt + c (ret1);
393         ADD,DC  ht_0,%r0,ht_0             ; ht++
394
395     ADD     ht_0,lt_1,lt_1            ; lt = lt + c (ht_0)
396     ADD,DC  ht_1,%r0,ht_1             ; ht++
397     STD     lt_0,0(r_ptr)             ; rp[0] = lt
398     STD     lt_1,8(r_ptr)             ; rp[1] = lt
399
400         COPY    ht_1,%ret1                ; carry = ht
401         LDO    -2(num),num                ; num = num - 2;
402     LDO     16(a_ptr),a_ptr           ; ap += 2
403         CMPIB,<= 2,num,bn_mul_words_unroll2
404     LDO     16(r_ptr),r_ptr           ; rp++
405
406     CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
407
408         ;
409         ; Top of loop aligned on 64-byte boundary
410         ;
411 bn_mul_words_single_top
412     FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
413
414     XMPYU   fht_0,fw_l,fm1            ; m1 = ht*fw_l
415     FSTD    fm1,-16(%sp)              ; -16(sp) = m1
416     XMPYU   flt_0,fw_h,fm             ; m = lt*fw_h
417     FSTD    fm,-8(%sp)                ; -8(sp) = m
418     XMPYU   fht_0,fw_h,ht_temp        ; ht_temp = ht*fw_h
419     FSTD    ht_temp,-24(%sp)          ; -24(sp) = ht
420     XMPYU   flt_0,fw_l,lt_temp        ; lt_temp = lt*fw_l
421     FSTD    lt_temp,-32(%sp)          ; -32(sp) = lt 
422
423     LDD     -8(%sp),m_0               
424     LDD    -16(%sp),m1_0              
425     ADD,L   m_0,m1_0,tmp_0            ; tmp_0 = m + m1; 
426     LDD     -24(%sp),ht_0             
427     LDD     -32(%sp),lt_0             
428
429     CMPCLR,*>>= tmp_0,m1_0,%r0        ; if (m < m1)
430     ADD,L   ht_0,top_overflow,ht_0    ; ht += (1<<32)
431
432     EXTRD,U tmp_0,31,32,m_0           ; m>>32  
433     DEPD,Z  tmp_0,31,32,m1_0          ; m1 = m<<32 
434
435     ADD,L   ht_0,m_0,ht_0             ; ht+= (m>>32)
436     ADD     lt_0,m1_0,lt_0            ; lt= lt+m1;
437     ADD,DC  ht_0,%r0,ht_0             ; ht++
438
439     ADD     %ret1,lt_0,lt_0           ; lt = lt + c;
440     ADD,DC  ht_0,%r0,ht_0             ; ht++
441
442     COPY    ht_0,%ret1                ; copy carry
443     STD     lt_0,0(r_ptr)             ; rp[0] = lt
444
445 bn_mul_words_exit
446     .EXIT
447     EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
448     LDD     -96(%sp),%r7              ; restore r7  
449     LDD     -104(%sp),%r6             ; restore r6  
450     LDD     -112(%sp),%r5             ; restore r5  
451     LDD     -120(%sp),%r4             ; restore r4  
452     BVE     (%rp)
453     LDD,MB  -128(%sp),%r3             ; restore r3
454         .PROCEND        
455
456 ;----------------------------------------------------------------------------
457 ;
458 ;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
459 ;
460 ; arg0 = rp
461 ; arg1 = ap
462 ; arg2 = num
463 ;
464
465 bn_sqr_words
466         .proc
467         .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
468         .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
469     .entry
470         .align 64
471
472     STD     %r3,0(%sp)          ; save r3  
473     STD     %r4,8(%sp)          ; save r4  
474         NOP
475     STD     %r5,16(%sp)         ; save r5  
476
477     CMPIB,>= 0,num,bn_sqr_words_exit
478         LDO     128(%sp),%sp       ; bump stack
479
480         ;
481         ; If only 1, the goto straight to cleanup
482         ;
483         CMPIB,= 1,num,bn_sqr_words_single_top
484     DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
485
486         ;
487         ; This loop is unrolled 2 times (64-byte aligned as well)
488         ;
489
490 bn_sqr_words_unroll2
491     FLDD    0(a_ptr),t_float_0        ; a[0]
492     FLDD    8(a_ptr),t_float_1        ; a[1]
493     XMPYU   fht_0,flt_0,fm            ; m[0]
494     XMPYU   fht_1,flt_1,fm_1          ; m[1]
495
496     FSTD    fm,-24(%sp)               ; store m[0]
497     FSTD    fm_1,-56(%sp)             ; store m[1]
498     XMPYU   flt_0,flt_0,lt_temp       ; lt[0]
499     XMPYU   flt_1,flt_1,lt_temp_1     ; lt[1]
500
501     FSTD    lt_temp,-16(%sp)          ; store lt[0]
502     FSTD    lt_temp_1,-48(%sp)        ; store lt[1]
503     XMPYU   fht_0,fht_0,ht_temp       ; ht[0]
504     XMPYU   fht_1,fht_1,ht_temp_1     ; ht[1]
505
506     FSTD    ht_temp,-8(%sp)           ; store ht[0]
507     FSTD    ht_temp_1,-40(%sp)        ; store ht[1]
508     LDD     -24(%sp),m_0             
509     LDD     -56(%sp),m_1              
510
511     AND     m_0,high_mask,tmp_0       ; m[0] & Mask
512     AND     m_1,high_mask,tmp_1       ; m[1] & Mask
513     DEPD,Z  m_0,30,31,m_0             ; m[0] << 32+1
514     DEPD,Z  m_1,30,31,m_1             ; m[1] << 32+1
515
516     LDD     -16(%sp),lt_0        
517     LDD     -48(%sp),lt_1        
518     EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m[0]&Mask >> 32-1
519     EXTRD,U tmp_1,32,33,tmp_1         ; tmp_1 = m[1]&Mask >> 32-1
520
521     LDD     -8(%sp),ht_0            
522     LDD     -40(%sp),ht_1           
523     ADD,L   ht_0,tmp_0,ht_0           ; ht[0] += tmp_0
524     ADD,L   ht_1,tmp_1,ht_1           ; ht[1] += tmp_1
525
526     ADD     lt_0,m_0,lt_0             ; lt = lt+m
527     ADD,DC  ht_0,%r0,ht_0             ; ht[0]++
528     STD     lt_0,0(r_ptr)             ; rp[0] = lt[0]
529     STD     ht_0,8(r_ptr)             ; rp[1] = ht[1]
530
531     ADD     lt_1,m_1,lt_1             ; lt = lt+m
532     ADD,DC  ht_1,%r0,ht_1             ; ht[1]++
533     STD     lt_1,16(r_ptr)            ; rp[2] = lt[1]
534     STD     ht_1,24(r_ptr)            ; rp[3] = ht[1]
535
536         LDO    -2(num),num                ; num = num - 2;
537     LDO     16(a_ptr),a_ptr           ; ap += 2
538         CMPIB,<= 2,num,bn_sqr_words_unroll2
539     LDO     32(r_ptr),r_ptr           ; rp += 4
540
541     CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
542
543         ;
544         ; Top of loop aligned on 64-byte boundary
545         ;
546 bn_sqr_words_single_top
547     FLDD    0(a_ptr),t_float_0        ; load up 64-bit value (fr8L) ht(L)/lt(R)
548
549     XMPYU   fht_0,flt_0,fm            ; m
550     FSTD    fm,-24(%sp)               ; store m
551
552     XMPYU   flt_0,flt_0,lt_temp       ; lt
553     FSTD    lt_temp,-16(%sp)          ; store lt
554
555     XMPYU   fht_0,fht_0,ht_temp       ; ht
556     FSTD    ht_temp,-8(%sp)           ; store ht
557
558     LDD     -24(%sp),m_0              ; load m
559     AND     m_0,high_mask,tmp_0       ; m & Mask
560     DEPD,Z  m_0,30,31,m_0             ; m << 32+1
561     LDD     -16(%sp),lt_0             ; lt
562
563     LDD     -8(%sp),ht_0              ; ht
564     EXTRD,U tmp_0,32,33,tmp_0         ; tmp_0 = m&Mask >> 32-1
565     ADD     m_0,lt_0,lt_0             ; lt = lt+m
566     ADD,L   ht_0,tmp_0,ht_0           ; ht += tmp_0
567     ADD,DC  ht_0,%r0,ht_0             ; ht++
568
569     STD     lt_0,0(r_ptr)             ; rp[0] = lt
570     STD     ht_0,8(r_ptr)             ; rp[1] = ht
571
572 bn_sqr_words_exit
573     .EXIT
574     LDD     -112(%sp),%r5       ; restore r5  
575     LDD     -120(%sp),%r4       ; restore r4  
576     BVE     (%rp)
577     LDD,MB  -128(%sp),%r3 
578         .PROCEND        ;in=23,24,25,26,29;out=28;
579
580
581 ;----------------------------------------------------------------------------
582 ;
583 ;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
584 ;
585 ; arg0 = rp 
586 ; arg1 = ap
587 ; arg2 = bp 
588 ; arg3 = n
589
590 t  .reg %r22
591 b  .reg %r21
592 l  .reg %r20
593
594 bn_add_words
595         .proc
596     .entry
597         .callinfo
598         .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
599         .align 64
600
601     CMPIB,>= 0,n,bn_add_words_exit
602     COPY    %r0,%ret1           ; return 0 by default
603
604         ;
605         ; If 2 or more numbers do the loop
606         ;
607         CMPIB,= 1,n,bn_add_words_single_top
608         NOP
609
610         ;
611         ; This loop is unrolled 2 times (64-byte aligned as well)
612         ;
613 bn_add_words_unroll2
614         LDD     0(a_ptr),t
615         LDD     0(b_ptr),b
616         ADD     t,%ret1,t                    ; t = t+c;
617         ADD,DC  %r0,%r0,%ret1                ; set c to carry
618         ADD     t,b,l                        ; l = t + b[0]
619         ADD,DC  %ret1,%r0,%ret1              ; c+= carry
620         STD     l,0(r_ptr)
621
622         LDD     8(a_ptr),t
623         LDD     8(b_ptr),b
624         ADD     t,%ret1,t                     ; t = t+c;
625         ADD,DC  %r0,%r0,%ret1                 ; set c to carry
626         ADD     t,b,l                         ; l = t + b[0]
627         ADD,DC  %ret1,%r0,%ret1               ; c+= carry
628         STD     l,8(r_ptr)
629
630         LDO     -2(n),n
631         LDO     16(a_ptr),a_ptr
632         LDO     16(b_ptr),b_ptr
633
634         CMPIB,<= 2,n,bn_add_words_unroll2
635         LDO     16(r_ptr),r_ptr
636
637     CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
638
639 bn_add_words_single_top
640         LDD     0(a_ptr),t
641         LDD     0(b_ptr),b
642
643         ADD     t,%ret1,t                 ; t = t+c;
644         ADD,DC  %r0,%r0,%ret1             ; set c to carry (could use CMPCLR??)
645         ADD     t,b,l                     ; l = t + b[0]
646         ADD,DC  %ret1,%r0,%ret1           ; c+= carry
647         STD     l,0(r_ptr)
648
649 bn_add_words_exit
650     .EXIT
651     BVE     (%rp)
652     EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
653         .PROCEND        ;in=23,24,25,26,29;out=28;
654
655 ;----------------------------------------------------------------------------
656 ;
657 ;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
658 ;
659 ; arg0 = rp 
660 ; arg1 = ap
661 ; arg2 = bp 
662 ; arg3 = n
663
664 t1       .reg %r22
665 t2       .reg %r21
666 sub_tmp1 .reg %r20
667 sub_tmp2 .reg %r19
668
669
670 bn_sub_words
671         .proc
672         .callinfo 
673         .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
674     .entry
675         .align 64
676
677     CMPIB,>=  0,n,bn_sub_words_exit
678     COPY    %r0,%ret1           ; return 0 by default
679
680         ;
681         ; If 2 or more numbers do the loop
682         ;
683         CMPIB,= 1,n,bn_sub_words_single_top
684         NOP
685
686         ;
687         ; This loop is unrolled 2 times (64-byte aligned as well)
688         ;
689 bn_sub_words_unroll2
690         LDD     0(a_ptr),t1
691         LDD     0(b_ptr),t2
692         SUB     t1,t2,sub_tmp1           ; t3 = t1-t2; 
693         SUB     sub_tmp1,%ret1,sub_tmp1  ; t3 = t3- c; 
694
695         CMPCLR,*>> t1,t2,sub_tmp2        ; clear if t1 > t2
696         LDO      1(%r0),sub_tmp2
697         
698         CMPCLR,*= t1,t2,%r0
699         COPY    sub_tmp2,%ret1
700         STD     sub_tmp1,0(r_ptr)
701
702         LDD     8(a_ptr),t1
703         LDD     8(b_ptr),t2
704         SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
705         SUB     sub_tmp1,%ret1,sub_tmp1   ; t3 = t3- c; 
706         CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
707         LDO      1(%r0),sub_tmp2
708         
709         CMPCLR,*= t1,t2,%r0
710         COPY    sub_tmp2,%ret1
711         STD     sub_tmp1,8(r_ptr)
712
713         LDO     -2(n),n
714         LDO     16(a_ptr),a_ptr
715         LDO     16(b_ptr),b_ptr
716
717         CMPIB,<= 2,n,bn_sub_words_unroll2
718         LDO     16(r_ptr),r_ptr
719
720     CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
721
722 bn_sub_words_single_top
723         LDD     0(a_ptr),t1
724         LDD     0(b_ptr),t2
725         SUB     t1,t2,sub_tmp1            ; t3 = t1-t2; 
726         SUB     sub_tmp1,%ret1,sub_tmp1   ; t3 = t3- c; 
727         CMPCLR,*>> t1,t2,sub_tmp2         ; clear if t1 > t2
728         LDO      1(%r0),sub_tmp2
729         
730         CMPCLR,*= t1,t2,%r0
731         COPY    sub_tmp2,%ret1
732
733         STD     sub_tmp1,0(r_ptr)
734
735 bn_sub_words_exit
736     .EXIT
737     BVE     (%rp)
738     EXTRD,U %ret1,31,32,%ret0           ; for 32-bit, return in ret0/ret1
739         .PROCEND        ;in=23,24,25,26,29;out=28;
740
741 ;------------------------------------------------------------------------------
742 ;
743 ; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
744 ;
745 ; arg0 = h
746 ; arg1 = l
747 ; arg2 = d
748 ;
749 ; This is mainly just output from the HP C compiler.  
750 ;
751 ;------------------------------------------------------------------------------
752 bn_div_words
753         .PROC
754         .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN
755         .IMPORT BN_num_bits_word,CODE
756         ;--- not PIC    .IMPORT __iob,DATA
757         ;--- not PIC    .IMPORT fprintf,CODE
758         .IMPORT abort,CODE
759         .IMPORT $$div2U,MILLICODE
760         .CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
761         .ENTRY
762         STW     %r2,-20(%r30)   ;offset 0x8ec
763         STW,MA  %r3,192(%r30)   ;offset 0x8f0
764         STW     %r4,-188(%r30)  ;offset 0x8f4
765         DEPD    %r5,31,32,%r6   ;offset 0x8f8
766         STD     %r6,-184(%r30)  ;offset 0x8fc
767         DEPD    %r7,31,32,%r8   ;offset 0x900
768         STD     %r8,-176(%r30)  ;offset 0x904
769         STW     %r9,-168(%r30)  ;offset 0x908
770         LDD     -248(%r30),%r3  ;offset 0x90c
771         COPY    %r26,%r4        ;offset 0x910
772         COPY    %r24,%r5        ;offset 0x914
773         DEPD    %r25,31,32,%r4  ;offset 0x918
774         CMPB,*<>        %r3,%r0,$0006000C       ;offset 0x91c
775         DEPD    %r23,31,32,%r5  ;offset 0x920
776         MOVIB,TR        -1,%r29,$00060002       ;offset 0x924
777         EXTRD,U %r29,31,32,%r28 ;offset 0x928
778 $0006002A
779         LDO     -1(%r29),%r29   ;offset 0x92c
780         SUB     %r23,%r7,%r23   ;offset 0x930
781 $00060024
782         SUB     %r4,%r31,%r25   ;offset 0x934
783         AND     %r25,%r19,%r26  ;offset 0x938
784         CMPB,*<>,N      %r0,%r26,$00060046      ;offset 0x93c
785         DEPD,Z  %r25,31,32,%r20 ;offset 0x940
786         OR      %r20,%r24,%r21  ;offset 0x944
787         CMPB,*<<,N      %r21,%r23,$0006002A     ;offset 0x948
788         SUB     %r31,%r2,%r31   ;offset 0x94c
789 $00060046
790 $0006002E
791         DEPD,Z  %r23,31,32,%r25 ;offset 0x950
792         EXTRD,U %r23,31,32,%r26 ;offset 0x954
793         AND     %r25,%r19,%r24  ;offset 0x958
794         ADD,L   %r31,%r26,%r31  ;offset 0x95c
795         CMPCLR,*>>=     %r5,%r24,%r0    ;offset 0x960
796         LDO     1(%r31),%r31    ;offset 0x964
797 $00060032
798         CMPB,*<<=,N     %r31,%r4,$00060036      ;offset 0x968
799         LDO     -1(%r29),%r29   ;offset 0x96c
800         ADD,L   %r4,%r3,%r4     ;offset 0x970
801 $00060036
802         ADDIB,=,N       -1,%r8,$D0      ;offset 0x974
803         SUB     %r5,%r24,%r28   ;offset 0x978
804 $0006003A
805         SUB     %r4,%r31,%r24   ;offset 0x97c
806         SHRPD   %r24,%r28,32,%r4        ;offset 0x980
807         DEPD,Z  %r29,31,32,%r9  ;offset 0x984
808         DEPD,Z  %r28,31,32,%r5  ;offset 0x988
809 $0006001C
810         EXTRD,U %r4,31,32,%r31  ;offset 0x98c
811         CMPB,*<>,N      %r31,%r2,$00060020      ;offset 0x990
812         MOVB,TR %r6,%r29,$D1    ;offset 0x994
813         STD     %r29,-152(%r30) ;offset 0x998
814 $0006000C
815         EXTRD,U %r3,31,32,%r25  ;offset 0x99c
816         COPY    %r3,%r26        ;offset 0x9a0
817         EXTRD,U %r3,31,32,%r9   ;offset 0x9a4
818         EXTRD,U %r4,31,32,%r8   ;offset 0x9a8
819         .CALL   ARGW0=GR,ARGW1=GR,RTNVAL=GR     ;in=25,26;out=28;
820         B,L     BN_num_bits_word,%r2    ;offset 0x9ac
821         EXTRD,U %r5,31,32,%r7   ;offset 0x9b0
822         LDI     64,%r20 ;offset 0x9b4
823         DEPD    %r7,31,32,%r5   ;offset 0x9b8
824         DEPD    %r8,31,32,%r4   ;offset 0x9bc
825         DEPD    %r9,31,32,%r3   ;offset 0x9c0
826         CMPB,=  %r28,%r20,$00060012     ;offset 0x9c4
827         COPY    %r28,%r24       ;offset 0x9c8
828         MTSARCM %r24    ;offset 0x9cc
829         DEPDI,Z -1,%sar,1,%r19  ;offset 0x9d0
830         CMPB,*>>,N      %r4,%r19,$D2    ;offset 0x9d4
831 $00060012
832         SUBI    64,%r24,%r31    ;offset 0x9d8
833         CMPCLR,*<<      %r4,%r3,%r0     ;offset 0x9dc
834         SUB     %r4,%r3,%r4     ;offset 0x9e0
835 $00060016
836         CMPB,=  %r31,%r0,$0006001A      ;offset 0x9e4
837         COPY    %r0,%r9 ;offset 0x9e8
838         MTSARCM %r31    ;offset 0x9ec
839         DEPD,Z  %r3,%sar,64,%r3 ;offset 0x9f0
840         SUBI    64,%r31,%r26    ;offset 0x9f4
841         MTSAR   %r26    ;offset 0x9f8
842         SHRPD   %r4,%r5,%sar,%r4        ;offset 0x9fc
843         MTSARCM %r31    ;offset 0xa00
844         DEPD,Z  %r5,%sar,64,%r5 ;offset 0xa04
845 $0006001A
846         DEPDI,Z -1,31,32,%r19   ;offset 0xa08
847         AND     %r3,%r19,%r29   ;offset 0xa0c
848         EXTRD,U %r29,31,32,%r2  ;offset 0xa10
849         DEPDI,Z -1,63,32,%r6    ;offset 0xa14
850         MOVIB,TR        2,%r8,$0006001C ;offset 0xa18
851         EXTRD,U %r3,63,32,%r7   ;offset 0xa1c
852 $D2
853         ;--- not PIC    ADDIL   LR'__iob-$global$,%r27,%r1      ;offset 0xa20
854         ;--- not PIC    LDIL    LR'C$7,%r21     ;offset 0xa24
855         ;--- not PIC    LDO     RR'__iob-$global$+32(%r1),%r26  ;offset 0xa28
856         ;--- not PIC    .CALL   ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR    ;in=24,25,26;out=28;
857         ;--- not PIC    B,L     fprintf,%r2     ;offset 0xa2c
858         ;--- not PIC    LDO     RR'C$7(%r21),%r25       ;offset 0xa30
859         .CALL           ;
860         B,L     abort,%r2       ;offset 0xa34
861         NOP             ;offset 0xa38
862         B       $D3     ;offset 0xa3c
863         LDW     -212(%r30),%r2  ;offset 0xa40
864 $00060020
865         COPY    %r4,%r26        ;offset 0xa44
866         EXTRD,U %r4,31,32,%r25  ;offset 0xa48
867         COPY    %r2,%r24        ;offset 0xa4c
868         .CALL   ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
869         B,L     $$div2U,%r31    ;offset 0xa50
870         EXTRD,U %r2,31,32,%r23  ;offset 0xa54
871         DEPD    %r28,31,32,%r29 ;offset 0xa58
872 $00060022
873         STD     %r29,-152(%r30) ;offset 0xa5c
874 $D1
875         AND     %r5,%r19,%r24   ;offset 0xa60
876         EXTRD,U %r24,31,32,%r24 ;offset 0xa64
877         STW     %r2,-160(%r30)  ;offset 0xa68
878         STW     %r7,-128(%r30)  ;offset 0xa6c
879         FLDD    -152(%r30),%fr4 ;offset 0xa70
880         FLDD    -152(%r30),%fr7 ;offset 0xa74
881         FLDW    -160(%r30),%fr8L        ;offset 0xa78
882         FLDW    -128(%r30),%fr5L        ;offset 0xa7c
883         XMPYU   %fr8L,%fr7L,%fr10       ;offset 0xa80
884         FSTD    %fr10,-136(%r30)        ;offset 0xa84
885         XMPYU   %fr8L,%fr7R,%fr22       ;offset 0xa88
886         FSTD    %fr22,-144(%r30)        ;offset 0xa8c
887         XMPYU   %fr5L,%fr4L,%fr11       ;offset 0xa90
888         XMPYU   %fr5L,%fr4R,%fr23       ;offset 0xa94
889         FSTD    %fr11,-112(%r30)        ;offset 0xa98
890         FSTD    %fr23,-120(%r30)        ;offset 0xa9c
891         LDD     -136(%r30),%r28 ;offset 0xaa0
892         DEPD,Z  %r28,31,32,%r31 ;offset 0xaa4
893         LDD     -144(%r30),%r20 ;offset 0xaa8
894         ADD,L   %r20,%r31,%r31  ;offset 0xaac
895         LDD     -112(%r30),%r22 ;offset 0xab0
896         DEPD,Z  %r22,31,32,%r22 ;offset 0xab4
897         LDD     -120(%r30),%r21 ;offset 0xab8
898         B       $00060024       ;offset 0xabc
899         ADD,L   %r21,%r22,%r23  ;offset 0xac0
900 $D0
901         OR      %r9,%r29,%r29   ;offset 0xac4
902 $00060040
903         EXTRD,U %r29,31,32,%r28 ;offset 0xac8
904 $00060002
905 $L2
906         LDW     -212(%r30),%r2  ;offset 0xacc
907 $D3
908         LDW     -168(%r30),%r9  ;offset 0xad0
909         LDD     -176(%r30),%r8  ;offset 0xad4
910         EXTRD,U %r8,31,32,%r7   ;offset 0xad8
911         LDD     -184(%r30),%r6  ;offset 0xadc
912         EXTRD,U %r6,31,32,%r5   ;offset 0xae0
913         LDW     -188(%r30),%r4  ;offset 0xae4
914         BVE     (%r2)   ;offset 0xae8
915         .EXIT
916         LDW,MB  -192(%r30),%r3  ;offset 0xaec
917         .PROCEND        ;in=23,25;out=28,29;fpin=105,107;
918
919
920
921
922 ;----------------------------------------------------------------------------
923 ;
924 ; Registers to hold 64-bit values to manipulate.  The "L" part
925 ; of the register corresponds to the upper 32-bits, while the "R"
926 ; part corresponds to the lower 32-bits
927
928 ; Note, that when using b6 and b7, the code must save these before
929 ; using them because they are callee save registers 
930
931 ;
932 ; Floating point registers to use to save values that
933 ; are manipulated.  These don't collide with ftemp1-6 and
934 ; are all caller save registers
935 ;
936 a0        .reg %fr22
937 a0L       .reg %fr22L
938 a0R       .reg %fr22R
939
940 a1        .reg %fr23
941 a1L       .reg %fr23L
942 a1R       .reg %fr23R
943
944 a2        .reg %fr24
945 a2L       .reg %fr24L
946 a2R       .reg %fr24R
947
948 a3        .reg %fr25
949 a3L       .reg %fr25L
950 a3R       .reg %fr25R
951
952 a4        .reg %fr26
953 a4L       .reg %fr26L
954 a4R       .reg %fr26R
955
956 a5        .reg %fr27
957 a5L       .reg %fr27L
958 a5R       .reg %fr27R
959
960 a6        .reg %fr28
961 a6L       .reg %fr28L
962 a6R       .reg %fr28R
963
964 a7        .reg %fr29
965 a7L       .reg %fr29L
966 a7R       .reg %fr29R
967
968 b0        .reg %fr30
969 b0L       .reg %fr30L
970 b0R       .reg %fr30R
971
972 b1        .reg %fr31
973 b1L       .reg %fr31L
974 b1R       .reg %fr31R
975
976 ;
977 ; Temporary floating point variables, these are all caller save
978 ; registers
979 ;
980 ftemp1    .reg %fr4
981 ftemp2    .reg %fr5
982 ftemp3    .reg %fr6
983 ftemp4    .reg %fr7
984
985 ;
986 ; The B set of registers when used.
987 ;
988
989 b2        .reg %fr8
990 b2L       .reg %fr8L
991 b2R       .reg %fr8R
992
993 b3        .reg %fr9
994 b3L       .reg %fr9L
995 b3R       .reg %fr9R
996
997 b4        .reg %fr10
998 b4L       .reg %fr10L
999 b4R       .reg %fr10R
1000
1001 b5        .reg %fr11
1002 b5L       .reg %fr11L
1003 b5R       .reg %fr11R
1004
1005 b6        .reg %fr12
1006 b6L       .reg %fr12L
1007 b6R       .reg %fr12R
1008
1009 b7        .reg %fr13
1010 b7L       .reg %fr13L
1011 b7R       .reg %fr13R
1012
1013 c1           .reg %r21   ; only reg
1014 temp1        .reg %r20   ; only reg
1015 temp2        .reg %r19   ; only reg
1016 temp3        .reg %r31   ; only reg
1017
1018 m1           .reg %r28   
1019 c2           .reg %r23   
1020 high_one     .reg %r1
1021 ht           .reg %r6
1022 lt           .reg %r5
1023 m            .reg %r4
1024 c3           .reg %r3
1025
1026 SQR_ADD_C  .macro  A0L,A0R,C1,C2,C3
1027     XMPYU   A0L,A0R,ftemp1       ; m
1028     FSTD    ftemp1,-24(%sp)      ; store m
1029
1030     XMPYU   A0R,A0R,ftemp2       ; lt
1031     FSTD    ftemp2,-16(%sp)      ; store lt
1032
1033     XMPYU   A0L,A0L,ftemp3       ; ht
1034     FSTD    ftemp3,-8(%sp)       ; store ht
1035
1036     LDD     -24(%sp),m           ; load m
1037     AND     m,high_mask,temp2    ; m & Mask
1038     DEPD,Z  m,30,31,temp3        ; m << 32+1
1039     LDD     -16(%sp),lt          ; lt
1040
1041     LDD     -8(%sp),ht           ; ht
1042     EXTRD,U temp2,32,33,temp1    ; temp1 = m&Mask >> 32-1
1043     ADD     temp3,lt,lt          ; lt = lt+m
1044     ADD,L   ht,temp1,ht          ; ht += temp1
1045     ADD,DC  ht,%r0,ht            ; ht++
1046
1047     ADD     C1,lt,C1             ; c1=c1+lt
1048     ADD,DC  ht,%r0,ht            ; ht++
1049
1050     ADD     C2,ht,C2             ; c2=c2+ht
1051     ADD,DC  C3,%r0,C3            ; c3++
1052 .endm
1053
1054 SQR_ADD_C2 .macro  A0L,A0R,A1L,A1R,C1,C2,C3
1055     XMPYU   A0L,A1R,ftemp1          ; m1 = bl*ht
1056     FSTD    ftemp1,-16(%sp)         ;
1057     XMPYU   A0R,A1L,ftemp2          ; m = bh*lt
1058     FSTD    ftemp2,-8(%sp)          ;
1059     XMPYU   A0R,A1R,ftemp3          ; lt = bl*lt
1060     FSTD    ftemp3,-32(%sp)
1061     XMPYU   A0L,A1L,ftemp4          ; ht = bh*ht
1062     FSTD    ftemp4,-24(%sp)         ;
1063
1064     LDD     -8(%sp),m               ; r21 = m
1065     LDD     -16(%sp),m1             ; r19 = m1
1066     ADD,L   m,m1,m                  ; m+m1
1067
1068     DEPD,Z  m,31,32,temp3           ; (m+m1<<32)
1069     LDD     -24(%sp),ht             ; r24 = ht
1070
1071     CMPCLR,*>>= m,m1,%r0            ; if (m < m1)
1072     ADD,L   ht,high_one,ht          ; ht+=high_one
1073
1074     EXTRD,U m,31,32,temp1           ; m >> 32
1075     LDD     -32(%sp),lt             ; lt
1076     ADD,L   ht,temp1,ht             ; ht+= m>>32
1077     ADD     lt,temp3,lt             ; lt = lt+m1
1078     ADD,DC  ht,%r0,ht               ; ht++
1079
1080     ADD     ht,ht,ht                ; ht=ht+ht;
1081     ADD,DC  C3,%r0,C3               ; add in carry (c3++)
1082
1083     ADD     lt,lt,lt                ; lt=lt+lt;
1084     ADD,DC  ht,%r0,ht               ; add in carry (ht++)
1085
1086     ADD     C1,lt,C1                ; c1=c1+lt
1087     ADD,DC,*NUV ht,%r0,ht           ; add in carry (ht++)
1088     LDO     1(C3),C3              ; bump c3 if overflow,nullify otherwise
1089
1090     ADD     C2,ht,C2                ; c2 = c2 + ht
1091     ADD,DC  C3,%r0,C3             ; add in carry (c3++)
1092 .endm
1093
1094 ;
1095 ;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
1096 ; arg0 = r_ptr
1097 ; arg1 = a_ptr
1098 ;
1099
1100 bn_sqr_comba8
1101         .PROC
1102         .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
1103         .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
1104     .ENTRY
1105         .align 64
1106
1107     STD     %r3,0(%sp)          ; save r3
1108     STD     %r4,8(%sp)          ; save r4
1109     STD     %r5,16(%sp)         ; save r5
1110     STD     %r6,24(%sp)         ; save r6
1111
1112         ;
1113         ; Zero out carries
1114         ;
1115         COPY     %r0,c1
1116         COPY     %r0,c2
1117         COPY     %r0,c3
1118
1119         LDO      128(%sp),%sp       ; bump stack
1120     DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
1121     DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
1122
1123         ;
1124         ; Load up all of the values we are going to use
1125         ;
1126     FLDD     0(a_ptr),a0       
1127     FLDD     8(a_ptr),a1       
1128     FLDD    16(a_ptr),a2       
1129     FLDD    24(a_ptr),a3       
1130     FLDD    32(a_ptr),a4       
1131     FLDD    40(a_ptr),a5       
1132     FLDD    48(a_ptr),a6       
1133     FLDD    56(a_ptr),a7       
1134
1135         SQR_ADD_C a0L,a0R,c1,c2,c3
1136         STD     c1,0(r_ptr)          ; r[0] = c1;
1137         COPY    %r0,c1
1138
1139         SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
1140         STD     c2,8(r_ptr)          ; r[1] = c2;
1141         COPY    %r0,c2
1142
1143         SQR_ADD_C a1L,a1R,c3,c1,c2
1144         SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
1145         STD     c3,16(r_ptr)            ; r[2] = c3;
1146         COPY    %r0,c3
1147
1148         SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
1149         SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
1150         STD     c1,24(r_ptr)           ; r[3] = c1;
1151         COPY    %r0,c1
1152
1153         SQR_ADD_C a2L,a2R,c2,c3,c1
1154         SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
1155         SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
1156         STD     c2,32(r_ptr)          ; r[4] = c2;
1157         COPY    %r0,c2
1158
1159         SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
1160         SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
1161         SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
1162         STD     c3,40(r_ptr)          ; r[5] = c3;
1163         COPY    %r0,c3
1164
1165         SQR_ADD_C a3L,a3R,c1,c2,c3
1166         SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
1167         SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
1168         SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
1169         STD     c1,48(r_ptr)          ; r[6] = c1;
1170         COPY    %r0,c1
1171
1172         SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
1173         SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
1174         SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
1175         SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
1176         STD     c2,56(r_ptr)          ; r[7] = c2;
1177         COPY    %r0,c2
1178
1179         SQR_ADD_C a4L,a4R,c3,c1,c2
1180         SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
1181         SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
1182         SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
1183         STD     c3,64(r_ptr)          ; r[8] = c3;
1184         COPY    %r0,c3
1185
1186         SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
1187         SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
1188         SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
1189         STD     c1,72(r_ptr)          ; r[9] = c1;
1190         COPY    %r0,c1
1191
1192         SQR_ADD_C a5L,a5R,c2,c3,c1
1193         SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
1194         SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
1195         STD     c2,80(r_ptr)          ; r[10] = c2;
1196         COPY    %r0,c2
1197
1198         SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
1199         SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
1200         STD     c3,88(r_ptr)          ; r[11] = c3;
1201         COPY    %r0,c3
1202         
1203         SQR_ADD_C a6L,a6R,c1,c2,c3
1204         SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
1205         STD     c1,96(r_ptr)          ; r[12] = c1;
1206         COPY    %r0,c1
1207
1208         SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
1209         STD     c2,104(r_ptr)         ; r[13] = c2;
1210         COPY    %r0,c2
1211
1212         SQR_ADD_C a7L,a7R,c3,c1,c2
1213         STD     c3, 112(r_ptr)       ; r[14] = c3
1214         STD     c1, 120(r_ptr)       ; r[15] = c1
1215
1216     .EXIT
1217     LDD     -104(%sp),%r6        ; restore r6
1218     LDD     -112(%sp),%r5        ; restore r5
1219     LDD     -120(%sp),%r4        ; restore r4
1220     BVE     (%rp)
1221     LDD,MB  -128(%sp),%r3
1222
1223         .PROCEND        
1224
1225 ;-----------------------------------------------------------------------------
1226 ;
1227 ;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
1228 ; arg0 = r_ptr
1229 ; arg1 = a_ptr
1230 ;
1231
1232 bn_sqr_comba4
1233         .proc
1234         .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
1235         .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
1236     .entry
1237         .align 64
1238     STD     %r3,0(%sp)          ; save r3
1239     STD     %r4,8(%sp)          ; save r4
1240     STD     %r5,16(%sp)         ; save r5
1241     STD     %r6,24(%sp)         ; save r6
1242
1243         ;
1244         ; Zero out carries
1245         ;
1246         COPY     %r0,c1
1247         COPY     %r0,c2
1248         COPY     %r0,c3
1249
1250         LDO      128(%sp),%sp       ; bump stack
1251     DEPDI,Z -1,32,33,high_mask   ; Create Mask 0xffffffff80000000L
1252     DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
1253
1254         ;
1255         ; Load up all of the values we are going to use
1256         ;
1257     FLDD     0(a_ptr),a0       
1258     FLDD     8(a_ptr),a1       
1259     FLDD    16(a_ptr),a2       
1260     FLDD    24(a_ptr),a3       
1261     FLDD    32(a_ptr),a4       
1262     FLDD    40(a_ptr),a5       
1263     FLDD    48(a_ptr),a6       
1264     FLDD    56(a_ptr),a7       
1265
1266         SQR_ADD_C a0L,a0R,c1,c2,c3
1267
1268         STD     c1,0(r_ptr)          ; r[0] = c1;
1269         COPY    %r0,c1
1270
1271         SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
1272
1273         STD     c2,8(r_ptr)          ; r[1] = c2;
1274         COPY    %r0,c2
1275
1276         SQR_ADD_C a1L,a1R,c3,c1,c2
1277         SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
1278
1279         STD     c3,16(r_ptr)            ; r[2] = c3;
1280         COPY    %r0,c3
1281
1282         SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
1283         SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
1284
1285         STD     c1,24(r_ptr)           ; r[3] = c1;
1286         COPY    %r0,c1
1287
1288         SQR_ADD_C a2L,a2R,c2,c3,c1
1289         SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
1290
1291         STD     c2,32(r_ptr)           ; r[4] = c2;
1292         COPY    %r0,c2
1293
1294         SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
1295         STD     c3,40(r_ptr)           ; r[5] = c3;
1296         COPY    %r0,c3
1297
1298         SQR_ADD_C a3L,a3R,c1,c2,c3
1299         STD     c1,48(r_ptr)           ; r[6] = c1;
1300         STD     c2,56(r_ptr)           ; r[7] = c2;
1301
1302     .EXIT
1303     LDD     -104(%sp),%r6        ; restore r6
1304     LDD     -112(%sp),%r5        ; restore r5
1305     LDD     -120(%sp),%r4        ; restore r4
1306     BVE     (%rp)
1307     LDD,MB  -128(%sp),%r3
1308
1309         .PROCEND        
1310
1311
1312 ;---------------------------------------------------------------------------
1313
1314 MUL_ADD_C  .macro  A0L,A0R,B0L,B0R,C1,C2,C3
1315     XMPYU   A0L,B0R,ftemp1        ; m1 = bl*ht
1316     FSTD    ftemp1,-16(%sp)       ;
1317     XMPYU   A0R,B0L,ftemp2        ; m = bh*lt
1318     FSTD    ftemp2,-8(%sp)        ;
1319     XMPYU   A0R,B0R,ftemp3        ; lt = bl*lt
1320     FSTD    ftemp3,-32(%sp)
1321     XMPYU   A0L,B0L,ftemp4        ; ht = bh*ht
1322     FSTD    ftemp4,-24(%sp)       ;
1323
1324     LDD     -8(%sp),m             ; r21 = m
1325     LDD     -16(%sp),m1           ; r19 = m1
1326     ADD,L   m,m1,m                ; m+m1
1327
1328     DEPD,Z  m,31,32,temp3         ; (m+m1<<32)
1329     LDD     -24(%sp),ht           ; r24 = ht
1330
1331     CMPCLR,*>>= m,m1,%r0          ; if (m < m1)
1332     ADD,L   ht,high_one,ht        ; ht+=high_one
1333
1334     EXTRD,U m,31,32,temp1         ; m >> 32
1335     LDD     -32(%sp),lt           ; lt
1336     ADD,L   ht,temp1,ht           ; ht+= m>>32
1337     ADD     lt,temp3,lt           ; lt = lt+m1
1338     ADD,DC  ht,%r0,ht             ; ht++
1339
1340     ADD     C1,lt,C1              ; c1=c1+lt
1341     ADD,DC  ht,%r0,ht             ; bump c3 if overflow,nullify otherwise
1342
1343     ADD     C2,ht,C2              ; c2 = c2 + ht
1344     ADD,DC  C3,%r0,C3             ; add in carry (c3++)
1345 .endm
1346
1347
1348 ;
1349 ;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
1350 ; arg0 = r_ptr
1351 ; arg1 = a_ptr
1352 ; arg2 = b_ptr
1353 ;
1354
1355 bn_mul_comba8
1356         .proc
1357         .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
1358         .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
1359     .entry
1360         .align 64
1361
1362     STD     %r3,0(%sp)          ; save r3
1363     STD     %r4,8(%sp)          ; save r4
1364     STD     %r5,16(%sp)         ; save r5
1365     STD     %r6,24(%sp)         ; save r6
1366     FSTD    %fr12,32(%sp)       ; save r6
1367     FSTD    %fr13,40(%sp)       ; save r7
1368
1369         ;
1370         ; Zero out carries
1371         ;
1372         COPY     %r0,c1
1373         COPY     %r0,c2
1374         COPY     %r0,c3
1375
1376         LDO      128(%sp),%sp       ; bump stack
1377     DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
1378
1379         ;
1380         ; Load up all of the values we are going to use
1381         ;
1382     FLDD      0(a_ptr),a0       
1383     FLDD      8(a_ptr),a1       
1384     FLDD     16(a_ptr),a2       
1385     FLDD     24(a_ptr),a3       
1386     FLDD     32(a_ptr),a4       
1387     FLDD     40(a_ptr),a5       
1388     FLDD     48(a_ptr),a6       
1389     FLDD     56(a_ptr),a7       
1390
1391     FLDD      0(b_ptr),b0       
1392     FLDD      8(b_ptr),b1       
1393     FLDD     16(b_ptr),b2       
1394     FLDD     24(b_ptr),b3       
1395     FLDD     32(b_ptr),b4       
1396     FLDD     40(b_ptr),b5       
1397     FLDD     48(b_ptr),b6       
1398     FLDD     56(b_ptr),b7       
1399
1400         MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
1401         STD       c1,0(r_ptr)
1402         COPY      %r0,c1
1403
1404         MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
1405         MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
1406         STD       c2,8(r_ptr)
1407         COPY      %r0,c2
1408
1409         MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
1410         MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
1411         MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
1412         STD       c3,16(r_ptr)
1413         COPY      %r0,c3
1414
1415         MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
1416         MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
1417         MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
1418         MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
1419         STD       c1,24(r_ptr)
1420         COPY      %r0,c1
1421
1422         MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
1423         MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
1424         MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
1425         MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
1426         MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
1427         STD       c2,32(r_ptr)
1428         COPY      %r0,c2
1429
1430         MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
1431         MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
1432         MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
1433         MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
1434         MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
1435         MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
1436         STD       c3,40(r_ptr)
1437         COPY      %r0,c3
1438
1439         MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
1440         MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
1441         MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
1442         MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
1443         MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
1444         MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
1445         MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
1446         STD       c1,48(r_ptr)
1447         COPY      %r0,c1
1448         
1449         MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
1450         MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
1451         MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
1452         MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
1453         MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
1454         MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
1455         MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
1456         MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
1457         STD       c2,56(r_ptr)
1458         COPY      %r0,c2
1459
1460         MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
1461         MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
1462         MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
1463         MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
1464         MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
1465         MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
1466         MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
1467         STD       c3,64(r_ptr)
1468         COPY      %r0,c3
1469
1470         MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
1471         MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
1472         MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
1473         MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
1474         MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
1475         MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
1476         STD       c1,72(r_ptr)
1477         COPY      %r0,c1
1478
1479         MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
1480         MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
1481         MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
1482         MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
1483         MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
1484         STD       c2,80(r_ptr)
1485         COPY      %r0,c2
1486
1487         MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
1488         MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
1489         MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
1490         MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
1491         STD       c3,88(r_ptr)
1492         COPY      %r0,c3
1493
1494         MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
1495         MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
1496         MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
1497         STD       c1,96(r_ptr)
1498         COPY      %r0,c1
1499
1500         MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
1501         MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
1502         STD       c2,104(r_ptr)
1503         COPY      %r0,c2
1504
1505         MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
1506         STD       c3,112(r_ptr)
1507         STD       c1,120(r_ptr)
1508
1509     .EXIT
1510     FLDD    -88(%sp),%fr13 
1511     FLDD    -96(%sp),%fr12 
1512     LDD     -104(%sp),%r6        ; restore r6
1513     LDD     -112(%sp),%r5        ; restore r5
1514     LDD     -120(%sp),%r4        ; restore r4
1515     BVE     (%rp)
1516     LDD,MB  -128(%sp),%r3
1517
1518         .PROCEND        
1519
1520 ;-----------------------------------------------------------------------------
1521 ;
1522 ;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
1523 ; arg0 = r_ptr
1524 ; arg1 = a_ptr
1525 ; arg2 = b_ptr
1526 ;
1527
1528 bn_mul_comba4
1529         .proc
1530         .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
1531         .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
1532     .entry
1533         .align 64
1534
1535     STD     %r3,0(%sp)          ; save r3
1536     STD     %r4,8(%sp)          ; save r4
1537     STD     %r5,16(%sp)         ; save r5
1538     STD     %r6,24(%sp)         ; save r6
1539     FSTD    %fr12,32(%sp)       ; save r6
1540     FSTD    %fr13,40(%sp)       ; save r7
1541
1542         ;
1543         ; Zero out carries
1544         ;
1545         COPY     %r0,c1
1546         COPY     %r0,c2
1547         COPY     %r0,c3
1548
1549         LDO      128(%sp),%sp       ; bump stack
1550     DEPDI,Z  1,31,1,high_one     ; Create Value  1 << 32
1551
1552         ;
1553         ; Load up all of the values we are going to use
1554         ;
1555     FLDD      0(a_ptr),a0       
1556     FLDD      8(a_ptr),a1       
1557     FLDD     16(a_ptr),a2       
1558     FLDD     24(a_ptr),a3       
1559
1560     FLDD      0(b_ptr),b0       
1561     FLDD      8(b_ptr),b1       
1562     FLDD     16(b_ptr),b2       
1563     FLDD     24(b_ptr),b3       
1564
1565         MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
1566         STD       c1,0(r_ptr)
1567         COPY      %r0,c1
1568
1569         MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
1570         MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
1571         STD       c2,8(r_ptr)
1572         COPY      %r0,c2
1573
1574         MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
1575         MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
1576         MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
1577         STD       c3,16(r_ptr)
1578         COPY      %r0,c3
1579
1580         MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
1581         MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
1582         MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
1583         MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
1584         STD       c1,24(r_ptr)
1585         COPY      %r0,c1
1586
1587         MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
1588         MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
1589         MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
1590         STD       c2,32(r_ptr)
1591         COPY      %r0,c2
1592
1593         MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
1594         MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
1595         STD       c3,40(r_ptr)
1596         COPY      %r0,c3
1597
1598         MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
1599         STD       c1,48(r_ptr)
1600         STD       c2,56(r_ptr)
1601
1602     .EXIT
1603     FLDD    -88(%sp),%fr13 
1604     FLDD    -96(%sp),%fr12 
1605     LDD     -104(%sp),%r6        ; restore r6
1606     LDD     -112(%sp),%r5        ; restore r5
1607     LDD     -120(%sp),%r4        ; restore r4
1608     BVE     (%rp)
1609     LDD,MB  -128(%sp),%r3
1610
1611         .PROCEND        
1612
1613
1614 ;--- not PIC    .SPACE  $TEXT$
1615 ;--- not PIC    .SUBSPA $CODE$
1616 ;--- not PIC    .SPACE  $PRIVATE$,SORT=16
1617 ;--- not PIC    .IMPORT $global$,DATA
1618 ;--- not PIC    .SPACE  $TEXT$
1619 ;--- not PIC    .SUBSPA $CODE$
1620 ;--- not PIC    .SUBSPA $LIT$,ACCESS=0x2c
1621 ;--- not PIC    C$7
1622 ;--- not PIC    .ALIGN  8
1623 ;--- not PIC    .STRINGZ        "Division would overflow (%d)\n"
1624         .END