⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ull_div32.asm

📁 MMI层OBJ不能完全编译
💻 ASM
字号:
;******************************************************************************
;* ULL_DIV32.ASM  - 32 BIT STATE -  v2.54                                     *
;* Copyright (c) 1996-2004 Texas Instruments Incorporated                     *
;******************************************************************************

;****************************************************************************
;* ULL_DIV/ULL_MOD - DIVIDE TWO UNSIGNED 64 BIT NUMBERS.
;*  
;****************************************************************************
;*
;*   o DIVIDEND IS IN r0:r1 (r1:r0 IF LITTLE ENDIAN)
;*   o DIVISOR IS IN r2:r3  (r3:r2 IF LITTLE ENDIAN)
;*
;*   o QUOTIENT IS PLACED IN r2:r3  (r3:r2 IF LITTLE ENDIAN)
;*   o REMAINDER IS PLACED IN r0:r1 (r1:r0 IF LITTLE ENDIAN)
;*
;*   o DIVIDE BY ZERO RETURNS ZERO
;*
;****************************************************************************
	.state32

	.global ULL_DIV
	.global ULL_MOD

	.if .TMS470_LITTLE

dvnd_hi .set    r1                                  ; HIGH WORD OF DIVIDEND
dvnd_lo .set    r0                                  ; LOW WORD OF DIVIDEND
idvs_hi .set    r3				    ; HIGH WORD OF DIVISOR
idvs_lo .set    r2				    ; LOW WORD OF DIVISOR
rq_hi   .set    r3			  	    ; HIGH WORD OF RESULT QUO
rq_lo   .set    r2			  	    ; LOW WORD OF RESULT QUO
rr_hi   .set    r1				    ; HIGH WORD OF RESULT REM
rr_lo   .set    r0				    ; HIGH WORD OF RESULT REM

	.else

dvnd_hi .set    r0                                  ; HIGH WORD OF DIVIDEND
dvnd_lo .set    r1                                  ; LOW WORD OF DIVIDEND
idvs_hi .set    r2				    ; HIGH WORD OF DIVISOR
idvs_lo .set    r3				    ; LOW WORD OF DIVISOR
rq_hi   .set    r2			  	    ; HIGH WORD OF RESULT QUO
rq_lo   .set    r3			  	    ; LOW WORD OF RESULT QUO
rr_hi   .set    r0				    ; HIGH WORD OF RESULT REM
rr_lo   .set    r1				    ; HIGH WORD OF RESULT REM

	.endif


q_hi    .set    LR                                  ; HIGH WORD OF QUOTIENT
q_lo    .set    r8                                  ; LOW WORD OF QUOTIENT
;dvnd_hi .set    r0                                  ; HIGH WORD OF DIVIDEND
;dvnd_lo .set    r1                                  ; LOW WORD OF DIVIDEND
dvsr_hi .set    r4                                  ; HIGH WORD OF DIVISOR COPY
dvsr_lo .set    r5                                  ; LOW WORD OF DIVISOR COPY
tmp_hi  .set    r6                                  ; HIGH WORD OF TEMP
tmp_lo  .set    r7                                  ; LOW WORD OF TEMP

ULL_DIV: .asmfunc stack_usage(24)
ULL_MOD:
        STMFD     SP!, {r4-r8, lr}                  ;
        MOV       dvsr_hi, idvs_hi                  ; MAKE A COPY OF INPUT 
        MOV       dvsr_lo, idvs_lo                  ; DIVISOR (R2:R3) INTO DVSR

        CMP       dvsr_hi, dvnd_hi                  ; IF DVND < DVSR,
        CMPEQ     dvsr_lo, dvnd_lo                  ; RETURN Q=0, R=DVND 
        MOVHI     rq_hi, #0                         ;
        MOVHI     rq_lo, #0                         ;
        LDMHIFD   SP!, {r4-r8, pc}

        CMP       dvsr_hi, #0                       ; IF DVSR IS 0,
        CMPEQ     dvsr_lo, #0                       ; RETURN Q=0, R=0 
        MOVEQ     rr_lo, #0                         ;
        MOVEQ     rr_hi, #0                         ;
        LDMEQFD   SP!, {r4-r8, pc}                  ;

        MOV       q_lo, #0                          ; INITIALIZE THE QUOTIENT
        MOV       q_hi, #0                          ; TO ZERO

        ; CALCULATE THE MAXIMUM DIVISOR SHIFT AMOUNT WITH PSEUDO BINARY SEARCH
        ; IF DVND >> 32 > DVSR THEN DVSR = DVSR << 32

        CMP       dvsr_hi, #0                       ; IF (DVSR_HI == 0 AND 
        CMPEQ     dvsr_lo, dvnd_hi                  ;          DVSRLO < DVND_HI)
        MOVLS     dvsr_hi, dvsr_lo                  ;    DVSR_HI = DVSRLO
        MOVLS     dvsr_lo, #0                       ;    DVSR_LO = 0

        ; IF DVND >> 16 > DVSR THEN DVSR = DVSR << 16
        MOV       tmp_lo, dvnd_lo, LSR #16          ; SHIFT DVND BY 16 INTO
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #16  ; TMP                   
        MOV       tmp_hi, dvnd_hi, LSR #16          ; 
        CMP       dvsr_hi, tmp_hi                   ; COMPARE DVSR WITH TMP
        CMPEQ     dvsr_lo, tmp_lo                   ;
        MOVLS     dvsr_hi, dvsr_hi, LSL #16         ; SET DVSR = DVSR << 16
        ORRLS     dvsr_hi, dvsr_hi, dvsr_lo, LSR #16;
        MOVLS     dvsr_lo, dvsr_lo, LSL #16         ;

        ; IF DVND >> 16 > DVSR THEN DVSR = DVSR << 16
        MOV       tmp_lo, dvnd_lo, LSR #8           ; SHIFT DVND BY 16 INTO
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #24  ; TMP
        MOV       tmp_hi, dvnd_hi, LSR #8           ; 
        CMP       dvsr_hi, tmp_hi                   ; COMPARE DVSR WITH TMP
        CMPEQ     dvsr_lo, tmp_lo                   ;
        MOVLS     dvsr_hi, dvsr_hi, LSL #8          ; SET DVSR = DVSR << 8
        ORRLS     dvsr_hi, dvsr_hi, dvsr_lo, LSR #24;
        MOVLS     dvsr_lo, dvsr_lo, LSL #8          ;

        ; NOW FIND EXACTLY WHERE THE SHIFTED DIVISOR SHOULD BE SO THAT WE CAN
        ; JUMP INTO THE CORRECT LOCATION OF THE UNROLLED DIVIDE LOOP.
        MOV       tmp_lo, dvnd_lo, LSR #1           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #31  ;
        MOV       tmp_hi, dvnd_hi, LSR #1           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod1                              ;

        MOV       tmp_lo, dvnd_lo, LSR #2           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #30  ;
        MOV       tmp_hi, dvnd_hi, LSR #2           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod2                              ; BRANCHING INTO DIVIDE LOOP

        MOV       tmp_lo, dvnd_lo, LSR #3           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #29  ;
        MOV       tmp_hi, dvnd_hi, LSR #3           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod3                              ;

        MOV       tmp_lo, dvnd_lo, LSR #4           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #28  ;
        MOV       tmp_hi, dvnd_hi, LSR #4           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod4                              ;

        MOV       tmp_lo, dvnd_lo, LSR #5           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #27  ;
        MOV       tmp_hi, dvnd_hi, LSR #5           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod5                              ;

        MOV       tmp_lo, dvnd_lo, LSR #6           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #26  ;
        MOV       tmp_hi, dvnd_hi, LSR #6           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod6                              ;

        MOV       tmp_lo, dvnd_lo, LSR #7           ;
        ORR       tmp_lo, tmp_lo, dvnd_hi, LSL #25  ;
        MOV       tmp_hi, dvnd_hi, LSR #7           ;
        CMP       dvsr_hi, tmp_hi                   ;
        CMPEQ     dvsr_lo, tmp_lo                   ;
        BHI       mod7                              ;

        ; THE DIVIDE LOOP IS UNROLLED 8 TIMES.
        ; IF DIVIDEND IS LARGER THAN DIVISOR, SHIFT A 1 INTO THE QUOTIENT
        ; AND SUBTRACT THE DIVISOR, ELSE SHIFT A 0 INTO THE QUOTIENT.
divll:
        MOV       tmp_hi, dvsr_hi, LSL #7           ; LEFT SHIFT DVSR BY 7 
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #25  ; INTO TMP
        MOV       tmp_lo, dvsr_lo, LSL #7           ;
        CMP       dvnd_hi, tmp_hi                   ; IF (DVND >= TMP)      
        CMPEQ     dvnd_lo, tmp_lo                   ; 
        BCC       $1                                ; 
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;    DVND = DVND - TMP
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$1:
        ADCS      q_lo, q_lo, q_lo                  ; SHIFT THE CARRY BIT DEFED
        ADC       q_hi, q_hi, q_hi                  ; BY CMP OR SBCS INTO THE 
                                                    ; QUOTIENT

mod7:
        MOV       tmp_hi, dvsr_hi, LSL #6           ; UNROLLED LOOP 
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #26  ;
        MOV       tmp_lo, dvsr_lo, LSL #6           ;
        CMP       dvnd_hi, tmp_hi                   ;
        CMPEQ     dvnd_lo, tmp_lo                   ;

        BCC       $2                                ;
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$2:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;
        
mod6:
        MOV       tmp_hi, dvsr_hi, LSL #5           ;
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #27  ;
        MOV       tmp_lo, dvsr_lo, LSL #5           ;
        CMP       dvnd_hi, tmp_hi                   ;
        CMPEQ     dvnd_lo, tmp_lo                   ;

        BCC       $3                                ;
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$3:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;
        
mod5:
        MOV       tmp_hi, dvsr_hi, LSL #4           ;
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #28  ;
        MOV       tmp_lo, dvsr_lo, LSL #4           ;
        CMP       dvnd_hi, tmp_hi                   ;
        CMPEQ     dvnd_lo, tmp_lo                   ;

        BCC       $4                                ;
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$4:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;
        
mod4:
        MOV       tmp_hi, dvsr_hi, LSL #3           ;
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #29  ;
        MOV       tmp_lo, dvsr_lo, LSL #3           ;
        CMP       dvnd_hi, tmp_hi                   ;
        CMPEQ     dvnd_lo, tmp_lo                   ;

        BCC       $5                                ;
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$5:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;
        
mod3:
        MOV       tmp_hi, dvsr_hi, LSL #2           ;
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #30  ;
        MOV       tmp_lo, dvsr_lo, LSL #2           ;
        CMP       dvnd_hi, tmp_hi                   ;
        CMPEQ     dvnd_lo, tmp_lo                   ;

        BCC       $6                                ;
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$6:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;
        
mod2:
        MOV       tmp_hi, dvsr_hi, LSL #1           ;
        ORR       tmp_hi, tmp_hi, dvsr_lo, LSR #31  ;
        MOV       tmp_lo, dvsr_lo, LSL #1           ;
        CMP       dvnd_hi, tmp_hi                   ;
        CMPEQ     dvnd_lo, tmp_lo                   ;

        BCC       $7                                ;
        SUBS      dvnd_lo, dvnd_lo, tmp_lo          ;
        SBCS      dvnd_hi, dvnd_hi, tmp_hi          ;
$7:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;

mod1:
        CMP       dvnd_hi, dvsr_hi                  ;
        CMPEQ     dvnd_lo, dvsr_lo                  ;
        
        BCC       $8                                ;
        SUBS      dvnd_lo, dvnd_lo, dvsr_lo         ;
        SBCS      dvnd_hi, dvnd_hi, dvsr_hi         ;
$8:
        ADCS      q_lo, q_lo, q_lo                  ;
        ADC       q_hi, q_hi, q_hi                  ;

        ; IF THERE IS SHIFTED DIVISOR, THEN UNSHIFT THE DIVISOR BY 8 AND
        ; CONTINUE THE LOOP
        CMP       idvs_hi, dvsr_hi                  ; 
        CMPEQ     idvs_lo, dvsr_lo                  ;
        MOVCC     dvsr_lo, dvsr_lo, LSR #8          ;
        ORRCC     dvsr_lo, dvsr_lo, dvsr_hi, LSL #24;
        MOVCC     dvsr_hi, dvsr_hi, LSR #8          ;
        BCC       divll                             ;

        ; ELSE WE ARE DONE. PLACE THE QUOTIENT INTO rq_hi:rq_lo. 
	; rr_hi:rr_lo ALREADY CONTAINS THE REMAINDER.
        MOV       rq_hi, q_hi                       ;
        MOV       rq_lo, q_lo                       ;

        LDMFD   SP!, {r4-r8, pc}                    ;
	.endasmfunc
        .end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -