Line No. | Rev | Author | Line |
---|---|---|---|
1 | 32 | kaklik | /********************************************************************** |
2 | ; * |
||
3 | ; * Big Integer Assembly Helpers |
||
4 | ; * Library for Microchip TCP/IP Stack |
||
5 | ; * - Accelerates processing for BigInt functions |
||
6 | ; * |
||
7 | ; ********************************************************************* |
||
8 | ; * FileName: BigInt_helper.S |
||
9 | ; * Dependencies: None |
||
10 | ; * Processor: PIC24F, PIC24H, dsPIC30F, dsPIC33F |
||
11 | ; * Compiler: Microchip C30 v3.12 or higher |
||
12 | ; * Company: Microchip Technology, Inc. |
||
13 | ; * |
||
14 | ; * Software License Agreement |
||
15 | ; * |
||
16 | ; * Copyright (C) 2002-2009 Microchip Technology Inc. All rights |
||
17 | ; * reserved. |
||
18 | ; * |
||
19 | ; * Microchip licenses to you the right to use, modify, copy, and |
||
20 | ; * distribute: |
||
21 | ; * (i) the Software when embedded on a Microchip microcontroller or |
||
22 | ; * digital signal controller product ("Device") which is |
||
23 | ; * integrated into Licensee's product; or |
||
24 | ; * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h, |
||
25 | ; * ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device |
||
26 | ; * used in conjunction with a Microchip ethernet controller for |
||
27 | ; * the sole purpose of interfacing with the ethernet controller. |
||
28 | ; * |
||
29 | ; * You should refer to the license agreement accompanying this |
||
30 | ; * Software for additional information regarding your rights and |
||
31 | ; * obligations. |
||
32 | ; * |
||
33 | ; * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT |
||
34 | ; * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT |
||
35 | ; * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A |
||
36 | ; * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
||
37 | ; * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR |
||
38 | ; * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF |
||
39 | ; * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS |
||
40 | ; * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE |
||
41 | ; * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER |
||
42 | ; * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT |
||
43 | ; * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE. |
||
44 | ; * |
||
45 | ; * |
||
46 | ; * Author Date Comment |
||
47 | ; *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
||
48 | ; * Elliott Wood 6/20/07 Original |
||
49 | ; * Howard Schlunder 9/12/07 Ported to 16-bit PICs |
||
50 | ; ********************************************************************/ |
||
51 | .equ VALID_ID,0 |
||
52 | .ifdecl __dsPIC30F |
||
53 | .include "p30fxxxx.inc" |
||
54 | .endif |
||
55 | .ifdecl __dsPIC33F |
||
56 | .include "p33fxxxx.inc" |
||
57 | .endif |
||
58 | .ifdecl __PIC24H |
||
59 | .include "p24hxxxx.inc" |
||
60 | .endif |
||
61 | .ifdecl __PIC24F |
||
62 | .include "p24fxxxx.inc" |
||
63 | .endif |
||
64 | .if VALID_ID <> 1 |
||
65 | //.error "Processor ID not specified in generic include files. New ASM30 assembler needs to be downloaded?" |
||
66 | .equ C,0 |
||
67 | .endif |
||
68 | |||
69 | //#define __GENERIC_TYPE_DEFS_H_ |
||
70 | //#define __COMPILER_H |
||
71 | //#include "HardwareProfile.h" |
||
72 | //#include "TCPIPConfig.h" |
||
73 | //#if (defined(STACK_USE_SSL_SERVER) || defined(STACK_USE_SSL_CLIENT)) && !defined(ENC100_INTERFACE_MODE) |
||
74 | |||
75 | |||
76 | .section BigInt_helper_vars,bss,near |
||
77 | .align 2 |
||
78 | .global __iA |
||
79 | .global __xA |
||
80 | .global __iB |
||
81 | .global __xB |
||
82 | .global __iR |
||
83 | .global __wC |
||
84 | __iA: .space 2 ;*_iA, starting index for A (lower memory address, least significant byte/word) |
||
85 | __xA: .space 2 ;*_xA, end index for A (higher memory address, most significant byte/word) |
||
86 | __iB: .space 2 ;*_iB, starting index for B (lower memory address, least significant byte/word) |
||
87 | __xB: .space 2 ;*_xB, end index for B (higher memory address, most significant byte/word) |
||
88 | __iR: .space 2 ;*_iR, starting index for Res (lower memory address, least significant byte/word) |
||
89 | __wC: .space 2 ; value of B for _mas (little endian word) |
||
90 | |||
91 | |||
92 | .text |
||
93 | |||
94 | ;*************************************************************************** |
||
95 | ; Function: void _addBI() |
||
96 | ; |
||
97 | ; PreCondition: _iA and _iB are loaded with the address of the LSB of the BigInt |
||
98 | ; _xA and _xB are loaded with the address of the MSB of the BigInt |
||
99 | ; a.size >= b.magnitude |
||
100 | ; |
||
101 | ; Input: A and B, the BigInts to add |
||
102 | ; |
||
103 | ; Output: A = A + B |
||
104 | ; |
||
105 | ; Side Effects: None |
||
106 | ; |
||
107 | ; Overview: Quickly performs the bulk addition of two BigInts |
||
108 | ; |
||
109 | ; Note: Function works |
||
110 | ;*************************************************************************** |
||
111 | .global __addBI |
||
112 | __addBI: |
||
113 | inc2 __xA, WREG ; W0 = one word past _xA |
||
114 | mov.w __iA, W2 |
||
115 | mov.w __xB, W3 |
||
116 | mov.w __iB, W4 |
||
117 | |||
118 | inc2 W3, W3 ; B end address needs to be one word past |
||
119 | bclr SR, #C ; C = 0 |
||
120 | |||
121 | ; Perform addition of all B words |
||
122 | aDoAdd: |
||
123 | mov.w [W4++], W1 ; Read B[i] |
||
124 | addc.w W1, [W2], [W2++] ; A[i] = A[i] + B[i] + C |
||
125 | xor.w W3, W4, W5 ; Is ++i past the MSB of B? |
||
126 | bra NZ, aDoAdd ; MSB not finished, go repeat loop |
||
127 | |||
128 | bra aFinalCarryCheck |
||
129 | |||
130 | ; Add in final carry out and propagate forward as needed |
||
131 | aDoFinalCarry: |
||
132 | addc.w W5, [W2], [W2++] ; W5 == 0, A[i] = A[i] + C |
||
133 | aFinalCarryCheck: |
||
134 | bra NC, aDone |
||
135 | xor.w W0, W2, W6 ; See if max address reached |
||
136 | bra NZ, aDoFinalCarry |
||
137 | |||
138 | aDone: |
||
139 | return |
||
140 | |||
141 | |||
142 | ;*************************************************************************** |
||
143 | ; Function: void _subBI() |
||
144 | ; |
||
145 | ; PreCondition: _iA and _iB are loaded with the address of the LSB of the BigInt |
||
146 | ; _xA and _xB are loaded with the address of the MSB of the BigInt |
||
147 | ; |
||
148 | ; Input: A and B, the BigInts to subtract |
||
149 | ; |
||
150 | ; Output: A = A - B |
||
151 | ; |
||
152 | ; Side Effects: None |
||
153 | ; |
||
154 | ; Overview: Quickly performs the bulk subtraction of two BigInts |
||
155 | ; |
||
156 | ; Note: Function works |
||
157 | ;*************************************************************************** |
||
158 | .global __subBI |
||
159 | __subBI: |
||
160 | inc2 __xA, WREG ; W0 = one word past _xA |
||
161 | mov.w __iA, W2 |
||
162 | mov.w __xB, W3 |
||
163 | mov.w __iB, W4 |
||
164 | |||
165 | inc2 W3, W3 ; B end address needs to be one word past |
||
166 | bset SR, #C ; Borrow = 0 |
||
167 | |||
168 | ; Perform subtraction of all B words |
||
169 | sDoSub: |
||
170 | mov.w [W4++], W1 ; Read B[i] |
||
171 | subbr.w W1, [W2], [W2++] ; A[i] = A[i] - B[i] - Borrow |
||
172 | xor.w W3, W4, W5 ; Is ++i past the MSB? |
||
173 | bra NZ, sDoSub ; MSB not finished, go repeat loop |
||
174 | |||
175 | bra sFinalBorrowCheck |
||
176 | |||
177 | ; Perform final borrow and propagate forward as needed |
||
178 | sDoFinalBorrow: |
||
179 | subbr.w W5, [W2], [W2++] ; W5 == 0, A[i] = A[i] - 0 - Borrow |
||
180 | sFinalBorrowCheck: |
||
181 | bra C, sDone |
||
182 | xor.w W0, W2, W6 ; See if max address reached |
||
183 | bra NZ, sDoFinalBorrow |
||
184 | |||
185 | sDone: |
||
186 | return |
||
187 | |||
188 | |||
189 | ;*************************************************************************** |
||
190 | ; Function: void _zeroBI() |
||
191 | ; |
||
192 | ; PreCondition: _iA is loaded with the address of the LSB of the BigInt |
||
193 | ; _xA is loaded with the address of the MSB of the BigInt |
||
194 | ; |
||
195 | ; Input: None |
||
196 | ; |
||
197 | ; Output: A = 0 |
||
198 | ; |
||
199 | ; Side Effects: None |
||
200 | ; |
||
201 | ; Overview: Sets all words from _iA to _xA to zero |
||
202 | ; |
||
203 | ; Note: Function works |
||
204 | ;*************************************************************************** |
||
205 | .global __zeroBI |
||
206 | __zeroBI: |
||
207 | inc2 __xA, WREG |
||
208 | mov __iA, W1 |
||
209 | |||
210 | zDoZero: |
||
211 | clr [W1++] |
||
212 | cp W0, W1 |
||
213 | bra NZ, zDoZero |
||
214 | |||
215 | return |
||
216 | |||
217 | |||
218 | ;*************************************************************************** |
||
219 | ; Function: void _msbBI() |
||
220 | ; |
||
221 | ; PreCondition: _iA is loaded with the address of the LSB of the BigInt buffer |
||
222 | ; _xA is loaded with the address of the right most byte of the BigInt buffer |
||
223 | ; |
||
224 | ; Input: None |
||
225 | ; |
||
226 | ; Output: _xA is now pointing to the MSB of the BigInt |
||
227 | ; |
||
228 | ; Side Effects: None |
||
229 | ; |
||
230 | ; Overview: Finds the MSB (first non-zero word) of the BigInt, starting |
||
231 | ; from the right-most word and testing to the left. This |
||
232 | ; function will stop if _iA is reached. |
||
233 | ; |
||
234 | ; Note: Function works |
||
235 | ;*************************************************************************** |
||
236 | .global __msbBI |
||
237 | __msbBI: |
||
238 | mov __xA, W0 |
||
239 | |||
240 | msbLoop: |
||
241 | cp __iA |
||
242 | bra Z, msbDone |
||
243 | cp0 [W0--] |
||
244 | bra Z, msbLoop |
||
245 | |||
246 | inc2 W0, W0 |
||
247 | |||
248 | msbDone: |
||
249 | mov W0, __xA |
||
250 | return |
||
251 | |||
252 | |||
253 | ;*************************************************************************** |
||
254 | ; Function: void _mulBI() |
||
255 | ; |
||
256 | ; PreCondition: _iA and _iB are loaded with the address of the LSB of each BigInt |
||
257 | ; _xA and _xB are loaded with the address of the MSB of the BigInt |
||
258 | ; _iR is loaded with the LSB address of the destination result memory |
||
259 | ; _iR memory must be zeroed and have enough space (_xB-_iB+_xA-_iA words) |
||
260 | ; |
||
261 | ; Input: A and B, the BigInts to multiply |
||
262 | ; |
||
263 | ; Output: R = A * B |
||
264 | ; |
||
265 | ; Side Effects: None |
||
266 | ; |
||
267 | ; Overview: Performs the bulk multiplication of two BigInts |
||
268 | ; |
||
269 | ; Note: Function works |
||
270 | ;*************************************************************************** |
||
271 | .global __mulBI |
||
272 | __mulBI: |
||
273 | push W8 |
||
274 | push W9 |
||
275 | |||
276 | ; Decement xA, xB (to match termination case) |
||
277 | ; W0 = xA + 2 (+2 for termination case) |
||
278 | ; W1 used for iA |
||
279 | ; W2 = xB + 2 (+2 for termination case) |
||
280 | ; W3 used for iB |
||
281 | ; W6:W7 used for multiplication result |
||
282 | ; W8 used for iR |
||
283 | ; W9 = 0x0000 |
||
284 | inc2 __xA, WREG |
||
285 | mov __xB, W2 |
||
286 | inc2 W2, W2 |
||
287 | |||
288 | mov __iB, W3 |
||
289 | mov __iR, W8 ; W8 = R for B loop |
||
290 | clr W9 |
||
291 | |||
292 | mLoopB: |
||
293 | cp W3, W2 ; Compare current iB and xB |
||
294 | bra Z, mDone |
||
295 | |||
296 | inc2 W8, W8 |
||
297 | mov [W3++], W5 ; Get current iB word |
||
298 | ; bra Z, mLoopB ; Skip this iB if it is zero |
||
299 | dec2 W8, W4 ; W4 = iR for A loop |
||
300 | mov __iA, W1 ; Load iA |
||
301 | |||
302 | mLoopA: |
||
303 | mul.uu W5, [W1++], W6 ; W7:W6 = B * A |
||
304 | add W6, [W4], [W4++] ; R = R + (B*A) |
||
305 | addc W7, [W4], [W4] |
||
306 | bra NC, mFinishedCarrying |
||
307 | mov W4, W6 |
||
308 | mKeepCarrying: |
||
309 | addc W9, [++W6], [W6] ; Add in residual carry to MSB of R and carry forward if it causes a carry out |
||
310 | bra C, mKeepCarrying |
||
311 | mFinishedCarrying: |
||
312 | |||
313 | cp W1, W0 |
||
314 | bra NZ, mLoopA |
||
315 | bra mLoopB |
||
316 | |||
317 | mDone: |
||
318 | pop W9 |
||
319 | pop W8 |
||
320 | return |
||
321 | |||
322 | |||
323 | ;*************************************************************************** |
||
324 | ; Function: void _sqrBI() |
||
325 | ; |
||
326 | ; PreCondition: _iA is loaded with the address of the LSB of the BigInt |
||
327 | ; _xA is loaded with the address of the MSB of the BigInt |
||
328 | ; _iR is loaded with the LSB address of the destination result memory |
||
329 | ; _iR memory must be zeroed and have enough space (_xB-_iB+_xA-_iA words) |
||
330 | ; |
||
331 | ; Input: A, the BigInt to square |
||
332 | ; |
||
333 | ; Output: R = A * A |
||
334 | ; |
||
335 | ; Side Effects: None |
||
336 | ; |
||
337 | ; Overview: Squares BigInt A and stores result in R |
||
338 | ; |
||
339 | ; Note: Function works |
||
340 | ;*************************************************************************** |
||
341 | .global __sqrBI |
||
342 | __sqrBI: |
||
343 | mov __iA, W0 |
||
344 | mov W0, __iB |
||
345 | mov __xA, W0 |
||
346 | mov W0, __xB |
||
347 | bra __mulBI |
||
348 | |||
349 | |||
350 | ;*************************************************************************** |
||
351 | ; Function: void _masBI() |
||
352 | ; |
||
353 | ; PreCondition: _iB is loaded with the LSB of the modulus BigInt |
||
354 | ; _xB is loaded with the MSB of the modulus BigInt |
||
355 | ; _wC is loaded with the 16 bit integer by which to multiply |
||
356 | ; _iR is the starting LSB of the decumulator BigInt |
||
357 | ; |
||
358 | ; Input: B (BigInt) and C (16-bit int) to multiply |
||
359 | ; |
||
360 | ; Output: R = R - (B * C) |
||
361 | ; |
||
362 | ; Side Effects: None |
||
363 | ; |
||
364 | ; Overview: Performs a Multiply And Subtract function. This is used in |
||
365 | ; the modulus calculation to save several steps. A BigInt (iB/xB) |
||
366 | ; is multiplied by a single word and subtracted rather than |
||
367 | ; accumulated. |
||
368 | ; |
||
369 | ; Note: Decumulator is the opposite of an accumulator, |
||
370 | ; if that wasn't obvious |
||
371 | ; |
||
372 | ; Note: Function works |
||
373 | ;*************************************************************************** |
||
374 | .global __masBI |
||
375 | __masBI: |
||
376 | ; Increment xB (to match termination case) |
||
377 | inc2 __xB, WREG |
||
378 | mov __iB, W1 |
||
379 | mov __wC, W2 |
||
380 | mov __iR, W3 |
||
381 | clr W5 ; Carry word |
||
382 | |||
383 | masLoop: |
||
384 | subr W5, [W3], [W3] ; Subtract carry word from R |
||
385 | clr W5 ; Clear carry word |
||
386 | btss SR, #C ; If a borrow occured |
||
387 | inc W5, W5 ; save 1 to the carry word |
||
388 | |||
389 | mul.uu W2, [W1++], W6 ; W7:W6 = B * C |
||
390 | subr W6, [W3], [W3++] ; R = R - (B * C) |
||
391 | btg SR, #C |
||
392 | addc W7, W5, W5 |
||
393 | |||
394 | cpseq W1, W0 ; Compare current B and xB |
||
395 | bra masLoop |
||
396 | |||
397 | subr W5, [W3], [W3] ; Finish borrowing |
||
398 | |||
399 | masDone: |
||
400 | return |
||
401 | |||
402 | |||
403 | ;*************************************************************************** |
||
404 | ; Function: void _copyBI() |
||
405 | ; |
||
406 | ; PreCondition: _iA and _iB are loaded with the address of the LSB of each BigInt |
||
407 | ; _xA and _xB are loaded with the address of the MSB of each BigInt |
||
408 | ; |
||
409 | ; Input: A and B, the destination and source |
||
410 | ; |
||
411 | ; Output: A = B |
||
412 | ; |
||
413 | ; Side Effects: None |
||
414 | ; |
||
415 | ; Stack Req: |
||
416 | ; |
||
417 | ; Overview: Copies a value from one BigInt to another |
||
418 | ; |
||
419 | ; Note: Function works |
||
420 | ;*************************************************************************** |
||
421 | .global __copyBI |
||
422 | __copyBI: |
||
423 | ; Incrmenet xA, xB (to match termination case) |
||
424 | inc2 __xA, WREG |
||
425 | mov W0, W1 |
||
426 | mov __iA, W2 |
||
427 | inc2 __xB, WREG |
||
428 | mov __iB, W4 |
||
429 | |||
430 | cLoop: |
||
431 | mov [W4++], [W2++] |
||
432 | cp W4, W0 |
||
433 | bra Z, cZeroLoopTest |
||
434 | cp W2, W1 |
||
435 | bra NZ, cLoop |
||
436 | return |
||
437 | |||
438 | cZeroLoop: |
||
439 | clr [W2++] |
||
440 | cZeroLoopTest: |
||
441 | cp W2, W1 |
||
442 | bra NZ, cZeroLoop |
||
443 | return |
||
444 | |||
445 | //#endif |
Powered by WebSVN v2.8.3