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

📄 tran.s

📁 arm嵌入式系统开发--软件设计与优化随书源代码。开发环境c。基本运算优化部分。
💻 S
字号:
;// ____________________________________________________________________
;//
;// Copyright (c) 2003, Andrew N. Sloss, Dominic Symes, Chris Wright
;// All rights reserved.
;// ____________________________________________________________________
;// 
;// NON-COMMERCIAL USE License
;// 
;// Redistribution and use in source and binary forms, with or without 
;// modification, are permitted provided that the following conditions 
;// are met: 
;//
;// 1. For NON-COMMERCIAL USE only.
;// 
;// 2. Redistributions of source code must retain the above copyright 
;//    notice, this list of conditions and the following disclaimer. 
;//
;// 3. Redistributions in binary form must reproduce the above 
;//    copyright notice, this list of conditions and the following 
;//    disclaimer in the documentation and/or other materials provided 
;//    with the distribution. 
;//
;// 4. All advertising materials mentioning features or use of this 
;//    software must display the following acknowledgement:
;//
;//    This product includes software developed by Andrew N. Sloss,
;//    Chris Wright and Dominic Symes. 
;//
;//  THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY 
;//  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
;//  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
;//  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE 
;//  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
;//  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
;//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
;//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
;//  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
;//  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
;//  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
;//  OF SUCH DAMAGE. 
;//
;// If you have questions about this license or would like a different
;// license please email : andrew@sloss.net
;//
;// Section 7.5: Transcendental functions

        AREA    ch07_5, CODE, READONLY

        EXPORT  ulog2_32
        EXPORT  uexp2_32
        EXPORT  sin_32
        EXPORT  cos_32

n       RN 0    ; Q0 input, Q26 log2 estimate
d       RN 1    ; normalise input Q32
r       RN 2
q       RN 3
t       RN 12

        ; int ulog2_32(unsigned n)
ulog2_32
        CLZ     r, n
        MOV     d, n, LSL#1
        MOV     d, d, LSL r       ; 1<=d<2 at Q32
        RSB     n, r, #31         ; integer part of the log
        MOV     r, d, LSR#27      ; estimate a=1+(r+0.5)/32
        ADR     t, ulog2_table
        LDR     r, [t, r, LSL#3]! ; r=log2(a) at Q26
        LDR     q, [t, #4]        ; q=1/a     at Q32
        MOV     t, #0
        UMLAL   t, r, d, r        ; r=(d/a)-1 at Q32
        LDR     t, =0x55555555    ; round(2^32/3)
        ADD     n, q, n, LSL#26   ; n+log2(a) at Q26
        SMULL   t, q, r, t        ; q = r/3   at Q32
        LDR     d, =0x05c551d9    ; round(2^26/ln(2))
        SMULL   t, q, r, q        ; q = r^2/3 at Q32
        MOV     t, #0
        SUB     q, q, r, ASR#1    ; q = -r/2+r^2/3 at Q32
        SMLAL   t, r, q, r        ; r - r^2/2 + r^3/3 at Q32
        MOV     t, #0
        SMLAL   t, n, d, r        ; n += r/log(2) at Q26
        MOV     pc, lr

ulog2_table
        ; table[2*i]  =round(2^32/a)     where a=1+(i+0.5)/32
        ; table[2*i+1]=round(2^26*log2(a)) and 0<=i<32
        DCD 0xfc0fc0fc, 0x0016e797, 0xf4898d60, 0x0043ace2
        DCD 0xed7303b6, 0x006f2109, 0xe6c2b448, 0x0099574f
        DCD 0xe070381c, 0x00c2615f, 0xda740da7, 0x00ea4f72
        DCD 0xd4c77b03, 0x0111307e, 0xcf6474a9, 0x0137124d
        DCD 0xca4587e7, 0x015c01a4, 0xc565c87b, 0x01800a56
        DCD 0xc0c0c0c1, 0x01a33761, 0xbc52640c, 0x01c592fb
        DCD 0xb81702e0, 0x01e726aa, 0xb40b40b4, 0x0207fb51
        DCD 0xb02c0b03, 0x0228193f, 0xac769184, 0x0247883b
        DCD 0xa8e83f57, 0x02664f8d, 0xa57eb503, 0x02847610
        DCD 0xa237c32b, 0x02a20231, 0x9f1165e7, 0x02bef9ff
        DCD 0x9c09c09c, 0x02db632d, 0x991f1a51, 0x02f7431f
        DCD 0x964fda6c, 0x03129ee9, 0x939a85c4, 0x032d7b5a
        DCD 0x90fdbc09, 0x0347dcfe, 0x8e78356d, 0x0361c825
        DCD 0x8c08c08c, 0x037b40e4, 0x89ae408a, 0x03944b1c
        DCD 0x8767ab5f, 0x03acea7c, 0x85340853, 0x03c52286
        DCD 0x83126e98, 0x03dcf68e, 0x81020408, 0x03f469c2

n       RN 0    ; input, integer part
d       RN 1    ; fractional part
r       RN 2
q       RN 3
t       RN 12

        ; unsigned uexp2_32(int n)
uexp2_32
        MOV     d, n, LSL#6      ; d = fractional part at Q32
        MOV     q, d, LSR#27     ; estimate a=(q+0.5)/32
        LDR     r, =0xb17217f8   ; round(2^32*log(2))
        BIC     d, d, q, LSL#27  ; d = d - (q/32) at Q32
        UMULL   t, d, r, d       ; d = d*log(2)   at Q32
        LDR     t, =0x55555555   ; round(2^32/3)
        SUB     d, d, r, LSR#6   ; d = d - log(2)/64 at Q32
        SMULL   t, r, d, t       ; r = d/3   at Q32
        MOVS    n, n, ASR#26     ; n = integer part of exponent
        SMULL   t, r, d, r       ; r = d^2/3 at Q32
        BMI     negative         ; catch negative exponent
        ADD     r, r, d          ; r = d+d^2/3
        SMULL   t, r, d, r       ; r = d^2+d^3/3
        ADR     t, uexp2_table
        LDR     q, [t, q, LSL#2] ; q = exp2(a) at Q31
        ADDS    r, d, r, ASR#1   ; r = d+d^2/2+d^3/6 at Q32
        UMULL   t, r, q, r       ; r = exp2(a)*r     at Q31 if r<0
        RSB     n, n, #31        ; 31-(integer part of exponent)
        ADDPL   r, r, q          ; correct if r>0
        MOV     n, r, LSR n      ; result at Q0
        MOV     pc, lr
negative
        MOV     r0, #0           ; 2^(-ve)=0
        MOV     pc, lr

uexp2_table
        ; table[i]=round(2^31*exp2(a)) where a=(i+0.5)/32
        DCD 0x8164d1f4, 0x843a28c4, 0x871f6197, 0x8a14d575
        DCD 0x8d1adf5b, 0x9031dc43, 0x935a2b2f, 0x96942d37
        DCD 0x99e04593, 0x9d3ed9a7, 0xa0b05110, 0xa43515ae
        DCD 0xa7cd93b5, 0xab7a39b6, 0xaf3b78ad, 0xb311c413
        DCD 0xb6fd91e3, 0xbaff5ab2, 0xbf1799b6, 0xc346ccda
        DCD 0xc78d74c9, 0xcbec14ff, 0xd06333db, 0xd4f35aac
        DCD 0xd99d15c2, 0xde60f482, 0xe33f8973, 0xe8396a50
        DCD 0xed4f301f, 0xf281773c, 0xf7d0df73, 0xfd3e0c0d

n       RN 0    ; the input angle in revolutions at Q32, result Q30
s       RN 1    ; the output sign
r       RN 2
q       RN 3
t       RN 12

cos_32  ; int cos_32(int n)
        EOR     s, n, n, LSL#1    ; cos is -ve in quadrants 1,2
        MOVS    n, n, LSL#1       ; angle in revolutions at Q33
        RSBMI   n, n, #0          ; in range 0-1/4 of a revolution
        CMP     n, #1<<30         ; if angle < 1/8 of a revolution
        BCC     cos_core          ; take cosine
        SUBEQ   n, n, #1          ; otherwise take sine of
        RSBHI   n, n, #1<<31      ; (1/4 revolution)-(angle)
sin_core                          ; take sine of Q33 angle n
        MOV     q, n, LSR#25      ; approximation a=(q+0.5)/32
        SUB     n, n, q, LSL#25   ; n = n-(q/32) at Q33
        SUB     n, n, #1<<24      ; n = n-(1/64) at Q33
        LDR     t, =0x6487ed51    ; round(2*PI*2^28)
        MOV     r, n, LSL#3       ; r = n at Q36
        SMULL   t, n, r, t        ; n = (x-a)*PI/2^31 at Q32
        ADR     t, cossin_tab
        LDR     q, [t, q, LSL#3]! ; c(a) at Q30
        LDR     t, [t, #4]        ; s(a) at Q30
        EOR     q, q, s, ASR#31   ; correct c(a) sign
        EOR     s, t, s, ASR#31   ; correct s(a) sign
        SMULL   t, r, n, n        ; n^2      at Q32
        SMULL   t, q, n, q        ; n*c(a)   at Q30
        SMULL   t, n, r, s        ; n^2*s(a) at Q30
        LDR     t, =0xd5555556    ; round(-2^32/6)
        SUB     n, s, n, ASR#1    ; n = s(a)*(1-n^2/2) at Q30
        SMULL   t, s, r, t        ; s=-n^2/6    at Q32
        ADD     n, n, q           ; n += c(a)*n        at Q30
        MOV     t, #0
        SMLAL   t, n, q, s        ; n += -c(a)*n^3/6   at Q30
        MOV     pc, lr            ; return n

sin_32  ; int sin_32(int n)
        AND     s, n, #1<<31      ; sin is -ve in quadrants 2,3
        MOVS    n, n, LSL#1       ; angle in revoluations at Q33
        RSBMI   n, n, #0          ; in range 0-1/4 of a revolution
        CMP     n, #1<<30         ; if angle < 1/8 revolution
        BCC     sin_core          ; take sine
        SUBEQ   n, n, #1          ; otherwise take cosine of
        RSBHI   n, n, #1<<31      ; (1/4 revolution)-(angle)
cos_core                          ; take cosine of Q33 angle n
        MOV     q, n, LSR#25      ; approximation a=(q+0.5)/32
        SUB     n, n, q, LSL#25   ; n = n-(q/32) at Q33
        SUB     n, n, #1<<24      ; n = n-(1/64) at Q33
        LDR     t, =0x6487ed51    ; round(2*PI*2^28)
        MOV     r, n, LSL#3       ; r = n at Q26
        SMULL   t, n, r, t        ; n = (x-a)*PI/2^31 at Q32
        ADR     t, cossin_tab
        LDR     q, [t, q, LSL#3]! ; c(a) at Q30
        LDR     t, [t, #4]        ; s(a) at Q30
        EOR     q, q, s, ASR#31   ; correct c(a) sign
        EOR     s, t, s, ASR#31   ; correct s(a) sign
        SMULL   t, r, n, n        ; n^2      at Q32
        SMULL   t, s, n, s        ; n*s(a)   at Q30
        SMULL   t, n, r, q        ; n^2*c(a) at Q30
        LDR     t, =0x2aaaaaab    ; round(+2^23/6)
        SUB     n, q, n, ASR#1    ; n = c(a)*(1-n^2/2) at Q30
        SMULL   t, q, r, t        ; n^2/6       at Q32
        SUB     n, n, s           ; n += -sin*n at Q30
        MOV     t, #0
        SMLAL   t, n, s, q        ; n += sin*n^3/6 at Q30
        MOV     pc, lr            ; return n

cossin_tab
        ; table[2*i]  =round(2^30*cos(a)) where a=(PI/4)*(i+0.5)/32
        ; table[2*i+1]=round(2^30*sin(a)) and 0 <= i < 32
        DCD 0x3ffec42d, 0x00c90e90, 0x3ff4e5e0, 0x025b0caf
        DCD 0x3fe12acb, 0x03ecadcf, 0x3fc395f9, 0x057db403
        DCD 0x3f9c2bfb, 0x070de172, 0x3f6af2e3, 0x089cf867
        DCD 0x3f2ff24a, 0x0a2abb59, 0x3eeb3347, 0x0bb6ecef
        DCD 0x3e9cc076, 0x0d415013, 0x3e44a5ef, 0x0ec9a7f3
        DCD 0x3de2f148, 0x104fb80e, 0x3d77b192, 0x11d3443f
        DCD 0x3d02f757, 0x135410c3, 0x3c84d496, 0x14d1e242
        DCD 0x3bfd5cc4, 0x164c7ddd, 0x3b6ca4c4, 0x17c3a931
        DCD 0x3ad2c2e8, 0x19372a64, 0x3a2fcee8, 0x1aa6c82b
        DCD 0x3983e1e8, 0x1c1249d8, 0x38cf1669, 0x1d79775c
        DCD 0x3811884d, 0x1edc1953, 0x374b54ce, 0x2039f90f
        DCD 0x367c9a7e, 0x2192e09b, 0x35a5793c, 0x22e69ac8
        DCD 0x34c61236, 0x2434f332, 0x33de87de, 0x257db64c
        DCD 0x32eefdea, 0x26c0b162, 0x31f79948, 0x27fdb2a7
        DCD 0x30f8801f, 0x29348937, 0x2ff1d9c7, 0x2a650525
        DCD 0x2ee3cebe, 0x2b8ef77d, 0x2dce88aa, 0x2cb2324c

        END

⌨️ 快捷键说明

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