|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
;
; multiply
; --------
;
; 32 bit fractional multiplication.
; 06/03/01 v0.00 P.Everett
;
; No checks are made for overflow.
; To assemble, using the 'as' assembler:
; as s.multiply -gcc -target SA1
;
; All have the following c declaration:
; long mul(long a1, long a2);
;
area |C$$code|, CODE, READONLY
align 4
;
; Signed fractional multiply by partial products.
; For use on non StrongARM machines.
;
; mul:
; ----
; Fractional multiply.
export |mul|
|mul|
stmfd sp!,{v1,v2,v3,lr}
; strip signs
cmps a1, #0 ; check sign of input
rsbmi a1, a1, #0 ; create abs of input
mvnmi a3, #0 ; save sign,
movpl a3, #0 ; of input
cmps a2, #0 ; check sign of other input
rsbmi a2, a2, #0 ; create abs of other input
mvnmi a4, #0 ; save sign,
movpl a4, #0 ; of other input
eor v3, a3, a4 ; combine signs and save
; unsigned long multiply
mov a3, a1, lsr #16 ; Split input ,
eor v1, a1, a3, lsl #16 ; into two halves.
mov a4, a2, lsr #16 ; Split other input,
eor v2, a2, a4, lsl #16 ; into two halves.
mul a1, a3, a4 ; Produce,
mul a2, v1, v2 ; the,
mul a3, v2, a3 ; partial,
mul a4, v1, a4 ; products.
adds a2, a2, a4, lsl #16 ; Combine,
adc a1, a1, a4, lsr #16 ; the,
adds a2, a2, a3, lsl #16 ; partial,
adc a1, a1, a3, lsr #16 ; products.
; make result signed
cmps v3, #0 ; check result sign
beq |exit_a| ; don't negate result if positive
rsbs a2, a2, #0 ; else negate,
rsc a1, a1, #0 ; the result.
|exit_a|
ldmfd sp!,{v1,v2,v3,pc}^ ; return, a1 = msw of result.
; muls:
; -----
; Fractional multiply with single bit left shift.
export |muls|
|muls|
stmfd sp!,{v1,v2,v3,lr}
; strip signs
cmps a1, #0 ; check sign of input
rsbmi a1, a1, #0 ; create abs of input
mvnmi a3, #0 ; save sign,
movpl a3, #0 ; of input
cmps a2, #0 ; check sign of other input
rsbmi a2, a2, #0 ; create abs of other input
mvnmi a4, #0 ; save sign,
movpl a4, #0 ; of other input
eor v3, a3, a4 ; combine signs and save
; unsigned long multiply
mov a3, a1, lsr #16 ; Split input ,
eor v1, a1, a3, lsl #16 ; into two halves.
mov a4, a2, lsr #16 ; Split other input,
eor v2, a2, a4, lsl #16 ; into two halves.
mul a1, a3, a4 ; Produce,
mul a2, v1, v2 ; the,
mul a3, v2, a3 ; partial,
mul a4, v1, a4 ; products.
adds a2, a2, a4, lsl #16 ; Combine,
adc a1, a1, a4, lsr #16 ; the,
adds a2, a2, a3, lsl #16 ; partial,
adc a1, a1, a3, lsr #16 ; products.
; make result signed
cmps v3, #0 ; check result sign
beq |exit_b| ; don't negate result if positive
rsbs a2, a2, #0 ; else negate,
rsc a1, a1, #0 ; the result.
|exit_b|
; shift and round
movs a2, a2, lsl #1 ; shift lsw 1 bit left,
adc a1, a1, a1 ; and msw, for fractional result.
ldmfd sp!,{v1,v2,v3,pc}^ ; return, a1 = msw of result.
; mulr:
; -----
; Fractional multiply with rounding.
export |mulr|
|mulr|
stmfd sp!,{v1,v2,v3,lr}
; strip signs
cmps a1, #0 ; check sign of input
rsbmi a1, a1, #0 ; create abs of input
mvnmi a3, #0 ; save sign,
movpl a3, #0 ; of input
cmps a2, #0 ; check sign of other input
rsbmi a2, a2, #0 ; create abs of other input
mvnmi a4, #0 ; save sign,
movpl a4, #0 ; of other input
eor v3, a3, a4 ; combine signs and save
; unsigned long multiply
mov a3, a1, lsr #16 ; Split input ,
eor v1, a1, a3, lsl #16 ; into two halves.
mov a4, a2, lsr #16 ; Split other input,
eor v2, a2, a4, lsl #16 ; into two halves.
mul a1, a3, a4 ; Produce,
mul a2, v1, v2 ; the,
mul a3, v2, a3 ; partial,
mul a4, v1, a4 ; products.
adds a2, a2, a4, lsl #16 ; Combine,
adc a1, a1, a4, lsr #16 ; the,
adds a2, a2, a3, lsl #16 ; partial,
adc a1, a1, a3, lsr #16 ; products.
; make result signed
cmps v3, #0 ; check result sign
beq |exit_c| ; don't negate result if positive
rsbs a2, a2, #0 ; else negate,
rsc a1, a1, #0 ; the result.
|exit_c|
; shift and round
adds a2, a2, #0x80000000 ; add 1 to the bit below,
adc a1, a1, #0 ; the msw for rounding.
ldmfd sp!,{v1,v2,v3,pc}^ ; return, a1 = msw of result.
; mulsr:
; ------
; Fractional multiply with single bit left shift and rounding.
export |mulsr|
|mulsr|
stmfd sp!,{v1,v2,v3,lr}
; strip signs
cmps a1, #0 ; check sign of input
rsbmi a1, a1, #0 ; create abs of input
mvnmi a3, #0 ; save sign,
movpl a3, #0 ; of input
cmps a2, #0 ; check sign of other input
rsbmi a2, a2, #0 ; create abs of other input
mvnmi a4, #0 ; save sign,
movpl a4, #0 ; of other input
eor v3, a3, a4 ; combine signs and save
; unsigned long multiply
mov a3, a1, lsr #16 ; Split input ,
eor v1, a1, a3, lsl #16 ; into two halves.
mov a4, a2, lsr #16 ; Split other input,
eor v2, a2, a4, lsl #16 ; into two halves.
mul a1, a3, a4 ; Produce,
mul a2, v1, v2 ; the,
mul a3, v2, a3 ; partial,
mul a4, v1, a4 ; products.
adds a2, a2, a4, lsl #16 ; Combine,
adc a1, a1, a4, lsr #16 ; the,
adds a2, a2, a3, lsl #16 ; partial,
adc a1, a1, a3, lsr #16 ; products.
; make result signed
cmps v3, #0 ; check result sign
beq |exit_d| ; don't negate result if positive
rsbs a2, a2, #0 ; else negate,
rsc a1, a1, #0 ; the result.
|exit_d|
; shift and round
movs a2, a2, lsl #1 ; shift lsw 1 bit left,
adc a1, a1, a1 ; and msw, for fractional result.
adds a2, a2, #0x80000000 ; add 1 to the bit below,
adc a1, a1, #0 ; the msw for rounding.
ldmfd sp!,{v1,v2,v3,pc}^ ; return, a1 = msw of result.
end
上面的一段汇编中,四个函数mul(), mulr(), muls(), mulsr() 均有如下函数原型:
long func(long a1, long a2)
由于来不及看arm的指令了,恳请熟悉arm汇编的朋友把相应的 c 函数片段写一下,或者给个提示也行,主要是移位和round的细节搞不清除。
先谢过了。 |
|