?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{FILE START}

library

?curdirlinks? - Rev 32

?prevdifflink? - Blame - ?getfile?

/**********************************************************************
; *
; *      Big Integer Assembly Helpers
; *  Library for Microchip TCP/IP Stack
; *       - Accelerates processing for BigInt functions
; *
; *********************************************************************
; * FileName:        BigInt_helper.S
; * Dependencies:    None
; * Processor:       PIC24F, PIC24H, dsPIC30F, dsPIC33F
; * Compiler:        Microchip C30 v3.12 or higher
; * Company:         Microchip Technology, Inc.
; *
; * Software License Agreement
; *
; * Copyright (C) 2002-2009 Microchip Technology Inc.  All rights
; * reserved.
; *
; * Microchip licenses to you the right to use, modify, copy, and
; * distribute:
; * (i)  the Software when embedded on a Microchip microcontroller or
; *      digital signal controller product ("Device") which is
; *      integrated into Licensee's product; or
; * (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
; *             ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
; *             used in conjunction with a Microchip ethernet controller for
; *             the sole purpose of interfacing with the ethernet controller.
; *
; * You should refer to the license agreement accompanying this
; * Software for additional information regarding your rights and
; * obligations.
; *
; * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
; * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
; * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
; * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
; * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
; * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
; * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
; * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
; * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
; * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
; * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
; *
; *
; * Author               Date           Comment
; *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; * Elliott Wood             6/20/07    Original
; * Howard Schlunder     9/12/07        Ported to 16-bit PICs
; ********************************************************************/
.equ VALID_ID,0
.ifdecl __dsPIC30F
        .include "p30fxxxx.inc"
.endif
.ifdecl __dsPIC33F
        .include "p33fxxxx.inc"
.endif
.ifdecl __PIC24H
        .include "p24hxxxx.inc"
.endif
.ifdecl __PIC24F
        .include "p24fxxxx.inc"
.endif
.if VALID_ID <> 1
        //.error "Processor ID not specified in generic include files.  New ASM30 assembler needs to be downloaded?"
        .equ C,0
.endif

//#define __GENERIC_TYPE_DEFS_H_
//#define __COMPILER_H
//#include "HardwareProfile.h"
//#include "TCPIPConfig.h"
//#if (defined(STACK_USE_SSL_SERVER) || defined(STACK_USE_SSL_CLIENT)) && !defined(ENC100_INTERFACE_MODE)


.section BigInt_helper_vars,bss,near
.align  2
.global __iA
.global __xA
.global __iB
.global __xB
.global __iR
.global __wC
__iA:   .space 2        ;*_iA, starting index for A (lower memory address, least significant byte/word)
__xA:   .space 2        ;*_xA, end index for A (higher memory address, most significant byte/word)
__iB:   .space 2        ;*_iB, starting index for B (lower memory address, least significant byte/word)
__xB:   .space 2        ;*_xB, end index for B (higher memory address, most significant byte/word)
__iR:   .space 2        ;*_iR, starting index for Res (lower memory address, least significant byte/word)
__wC:   .space 2        ; value of B for _mas (little endian word)


.text

;***************************************************************************
; Function:     void _addBI()
;
; PreCondition: _iA and _iB are loaded with the address of the LSB of the BigInt
;                               _xA and _xB are loaded with the address of the MSB of the BigInt
;                               a.size >= b.magnitude
;
; Input:                A and B, the BigInts to add
;
; Output:               A = A + B
;
; Side Effects: None
;
; Overview:     Quickly performs the bulk addition of two BigInts
;
; Note:                 Function works
;***************************************************************************
        .global __addBI
__addBI:
        inc2    __xA, WREG                      ; W0 = one word past _xA
        mov.w   __iA, W2
        mov.w   __xB, W3
        mov.w   __iB, W4

        inc2    W3, W3                          ; B end address needs to be one word past
        bclr    SR, #C                          ; C = 0

; Perform addition of all B words
aDoAdd:
        mov.w   [W4++], W1                      ; Read B[i]
        addc.w  W1, [W2], [W2++]        ; A[i] = A[i] + B[i] + C
        xor.w   W3, W4, W5                      ; Is ++i past the MSB of B?
        bra             NZ, aDoAdd                      ; MSB not finished, go repeat loop

        bra             aFinalCarryCheck

; Add in final carry out and propagate forward as needed
aDoFinalCarry:
        addc.w  W5, [W2], [W2++]        ; W5 == 0, A[i] = A[i] + C
aFinalCarryCheck:
        bra             NC, aDone
        xor.w   W0, W2, W6                      ; See if max address reached
        bra             NZ, aDoFinalCarry

aDone:
        return


;***************************************************************************
; Function:     void _subBI()
;
; PreCondition: _iA and _iB are loaded with the address of the LSB of the BigInt
;                               _xA and _xB are loaded with the address of the MSB of the BigInt
;
; Input:                A and B, the BigInts to subtract
;
; Output:               A = A - B
;
; Side Effects: None
;
; Overview:     Quickly performs the bulk subtraction of two BigInts
;
; Note:                 Function works
;***************************************************************************
        .global __subBI
__subBI:
        inc2    __xA, WREG                      ; W0 = one word past _xA
        mov.w   __iA, W2
        mov.w   __xB, W3
        mov.w   __iB, W4

        inc2    W3, W3                          ; B end address needs to be one word past
        bset    SR, #C                          ; Borrow = 0

; Perform subtraction of all B words
sDoSub:
        mov.w   [W4++], W1                      ; Read B[i]
        subbr.w W1, [W2], [W2++]        ; A[i] = A[i] - B[i] - Borrow
        xor.w   W3, W4, W5                      ; Is ++i past the MSB?
        bra             NZ, sDoSub                      ; MSB not finished, go repeat loop

        bra             sFinalBorrowCheck

; Perform final borrow and propagate forward as needed
sDoFinalBorrow:
        subbr.w W5, [W2], [W2++]        ; W5 == 0, A[i] = A[i] - 0 - Borrow
sFinalBorrowCheck:
        bra             C, sDone
        xor.w   W0, W2, W6                      ; See if max address reached
        bra             NZ, sDoFinalBorrow

sDone:
        return


;***************************************************************************
; Function:     void _zeroBI()
;
; PreCondition: _iA is loaded with the address of the LSB of the BigInt
;                               _xA is loaded with the address of the MSB of the BigInt
;
; Input:                None
;
; Output:               A = 0
;
; Side Effects: None
;
; Overview:     Sets all words from _iA to _xA to zero
;
; Note:                 Function works
;***************************************************************************
        .global __zeroBI
__zeroBI:
        inc2    __xA, WREG
        mov             __iA, W1

zDoZero:
        clr             [W1++]
        cp              W0, W1
        bra             NZ, zDoZero

        return


;***************************************************************************
; Function:     void _msbBI()
;
; PreCondition: _iA is loaded with the address of the LSB of the BigInt buffer
;                               _xA is loaded with the address of the right most byte of the BigInt buffer
;
; Input:                None
;
; Output:               _xA is now pointing to the MSB of the BigInt
;
; Side Effects: None
;
; Overview:     Finds the MSB (first non-zero word) of the BigInt, starting 
;                               from the right-most word and testing to the left.  This 
;                               function will stop if _iA is reached.
;
; Note:                 Function works
;***************************************************************************
        .global __msbBI
__msbBI:
        mov             __xA, W0
        
msbLoop:
        cp              __iA
        bra             Z, msbDone
        cp0             [W0--]
        bra             Z, msbLoop
        
        inc2    W0, W0

msbDone:
        mov             W0, __xA
        return


;***************************************************************************
; Function:     void _mulBI()
;
; PreCondition: _iA and _iB are loaded with the address of the LSB of each BigInt
;                               _xA and _xB are loaded with the address of the MSB of the BigInt
;                               _iR is loaded with the LSB address of the destination result memory
;                               _iR memory must be zeroed and have enough space (_xB-_iB+_xA-_iA words)
;
; Input:                A and B, the BigInts to multiply
;
; Output:               R = A * B
;
; Side Effects: None
;
; Overview:     Performs the bulk multiplication of two BigInts
;
; Note:                 Function works
;***************************************************************************
        .global __mulBI
__mulBI:
        push    W8
        push    W9

        ; Decement xA, xB (to match termination case)
        ; W0 = xA + 2   (+2 for termination case)
        ; W1 used for iA
        ; W2 = xB + 2   (+2 for termination case)
        ; W3 used for iB
        ; W6:W7 used for multiplication result
        ; W8 used for iR
        ; W9 = 0x0000
        inc2    __xA, WREG                      
        mov             __xB, W2                        
        inc2    W2, W2                          

        mov             __iB, W3
        mov             __iR, W8                        ; W8 = R for B loop
        clr             W9

mLoopB:
        cp              W3, W2                          ; Compare current iB and xB
        bra             Z, mDone
        
        inc2    W8, W8
        mov             [W3++], W5                      ; Get current iB word
;       bra             Z, mLoopB                       ; Skip this iB if it is zero
        dec2    W8, W4                          ; W4 = iR for A loop
        mov             __iA, W1                        ; Load iA

mLoopA:
        mul.uu  W5, [W1++], W6          ; W7:W6 = B * A
        add             W6, [W4], [W4++]        ; R = R + (B*A)
        addc    W7, [W4], [W4]
        bra             NC, mFinishedCarrying
        mov             W4, W6
mKeepCarrying:
        addc    W9, [++W6], [W6]        ; Add in residual carry to MSB of R and carry forward if it causes a carry out
        bra             C, mKeepCarrying
mFinishedCarrying:
        
        cp              W1, W0
        bra             NZ, mLoopA
        bra             mLoopB

mDone:
        pop             W9
        pop             W8
        return


;***************************************************************************
; Function:     void _sqrBI()
;
; PreCondition: _iA is loaded with the address of the LSB of the BigInt
;                               _xA is loaded with the address of the MSB of the BigInt
;                               _iR is loaded with the LSB address of the destination result memory
;                               _iR memory must be zeroed and have enough space (_xB-_iB+_xA-_iA words)
;
; Input:                A, the BigInt to square
;
; Output:               R = A * A
;
; Side Effects: None
;
; Overview:     Squares BigInt A and stores result in R
;
; Note:                 Function works
;***************************************************************************
        .global __sqrBI
__sqrBI:
        mov             __iA, W0
        mov             W0, __iB
        mov             __xA, W0
        mov             W0, __xB
        bra             __mulBI


;***************************************************************************
; Function:     void _masBI()
;
; PreCondition: _iB is loaded with the LSB of the modulus BigInt
;                               _xB is loaded with the MSB of the modulus BigInt
;                               _wC is loaded with the 16 bit integer by which to multiply
;                               _iR is the starting LSB of the decumulator BigInt
;
; Input:                B (BigInt) and C (16-bit int) to multiply
;
; Output:               R = R - (B * C)
;
; Side Effects: None
;
; Overview:     Performs a Multiply And Subtract function.  This is used in
;                               the modulus calculation to save several steps.  A BigInt (iB/xB)
;                               is multiplied by a single word and subtracted rather than
;                               accumulated.
;
; Note:                 Decumulator is the opposite of an accumulator,
;                               if that wasn't obvious
;
; Note:                 Function works
;***************************************************************************
        .global __masBI
__masBI:
        ; Increment xB (to match termination case)
        inc2    __xB, WREG
        mov             __iB, W1
        mov             __wC, W2
        mov             __iR, W3
        clr             W5                                      ; Carry word

masLoop:
        subr    W5, [W3], [W3]          ; Subtract carry word from R
        clr             W5                                      ; Clear carry word
        btss    SR, #C                          ; If a borrow occured
        inc             W5, W5                          ;       save 1 to the carry word
        
        mul.uu  W2, [W1++], W6          ; W7:W6 = B * C
        subr    W6, [W3], [W3++]        ; R = R - (B * C)
        btg             SR, #C
        addc    W7, W5, W5

        cpseq   W1, W0                          ; Compare current B and xB
        bra             masLoop
        
        subr    W5, [W3], [W3]          ; Finish borrowing
        
masDone:
        return


;***************************************************************************
; Function:     void _copyBI()
;
; PreCondition: _iA and _iB are loaded with the address of the LSB of each BigInt
;                               _xA and _xB are loaded with the address of the MSB of each BigInt
;
; Input:                A and B, the destination and source
;
; Output:               A = B
;
; Side Effects: None
;
; Stack Req:    
;
; Overview:     Copies a value from one BigInt to another
;
; Note:                 Function works
;***************************************************************************
        .global __copyBI
__copyBI:
        ; Incrmenet xA, xB (to match termination case)
        inc2    __xA, WREG
        mov             W0, W1
        mov             __iA, W2
        inc2    __xB, WREG
        mov             __iB, W4

cLoop:
        mov             [W4++], [W2++]
        cp              W4, W0
        bra             Z, cZeroLoopTest
        cp              W2, W1
        bra             NZ, cLoop
        return

cZeroLoop:
        clr             [W2++]
cZeroLoopTest:
        cp              W2, W1
        bra             NZ, cZeroLoop
        return  

//#endif
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3