📄 cpdo.s
字号:
/*The FP structure has 4 words reserved for each register, the first is used justfor the sign in bit 31, the second and third are for the mantissa (unsignedinteger, high 32 bit first) and the fourth is the exponent (signed integer).The mantissa is always normalized.If the exponent is 0x80000000, that is the most negative value, the numberrepresented is 0 and both mantissa words are also 0.If the exponent is 0x7fffffff, that is the biggest positive value, the numberrepresented is infinity if the high 32 mantissa bit are also 0, otherwise it isa NaN. The low 32 mantissa bit are 0 if the number represented is infinity.Decimal and packed decimal numbers are not supported yet.The parameters to these functions are r0=destination pointer, r1 and r2source pointers. r4 is the instruction. They may use r0-r8 and r14. They returnto fastfpe_next, except CPDO_rnf_core which expects the return address in r14.*//*---------------------------------------------------------------------------*/ .globl CPDO_adfCPDO_adf: ldmia r1,{r1,r3,r5,r7} ldmia r2,{r2,r4,r6,r8} cmp r7,#0x7fffffff cmpne r8,#0x7fffffff beq CPDO_adf_extra cmp r1,r2 bne CPDO_suf_sCPDO_adf_s: subs r2,r7,r8 bge CPDO_adf_2nd mov r7,r8 rsb r2,r2,#0 cmp r2,#32 ble CPDO_adf_1st2 sub r2,r2,#32 cmp r2,#32 movgt r2,#32 mov r5,r3,lsr r2 mov r3,#0 b CPDO_adf_addCPDO_adf_1st2: rsb r8,r2,#32 mov r5,r5,lsr r2 orr r5,r5,r3,lsl r8 mov r3,r3,lsr r2 @ 1. op normalized b CPDO_adf_addCPDO_adf_2nd: cmp r2,#32 ble CPDO_adf_2nd2 sub r2,r2,#32 cmp r2,#32 movgt r2,#32 mov r6,r4,lsr r2 mov r4,#0 b CPDO_adf_addCPDO_adf_2nd2: rsb r8,r2,#32 mov r6,r6,lsr r2 orr r6,r6,r4,lsl r8 mov r4,r4,lsr r2 @ 2. op normalizedCPDO_adf_add: adds r5,r5,r6 adcs r3,r3,r4 @ do addition bcc CPDO_adf_end add r7,r7,#1 movs r3,r3,rrx mov r5,r5,rrx @ correct for overflowCPDO_adf_end: cmp r7,#0x20000000 bge CPDO_inf stmia r0,{r1,r3,r5,r7} b fastfpe_nextCPDO_adf_extra: cmp r7,#0x7fffffff @ was it the 1st ? bne CPDO_infnan_2 @ no it was the 2nd cmp r8,#0x7fffffff @ if 1st, 2nd too ? bne CPDO_infnan_1 @ no only 1st cmp r3,#0 cmpeq r4,#0 bne CPDO_nan_12 b CPDO_inf/*---------------------------------------------------------------------------*/CPDO_infnan_1: stmia r0,{r1,r3,r5,r7} b fastfpe_nextCPDO_infnan_2: stmia r0,{r2,r4,r6,r8} b fastfpe_next CPDO_nan_12: orr r2,r3,r4 b CPDO_inf_1CPDO_nan: mov r2,#0x40000000 @ create non signalling NaN b CPDO_inf_1CPDO_inf: mov r2,#0CPDO_inf_1: mov r3,#0 mov r4,#0x7fffffffCPDO_store_1234: stmia r0,{r1,r2,r3,r4} b fastfpe_nextCPDO_zero: mov r1,#0CPDO_zero_1: mov r2,#0 mov r3,#0 mov r4,#0x80000000 stmia r0,{r1,r2,r3,r4} b fastfpe_next/*---------------------------------------------------------------------------*/ .globl CPDO_sufCPDO_suf: ldmia r1,{r1,r3,r5,r7} ldmia r2,{r2,r4,r6,r8}CPDO_suf_l: cmp r7,#0x7fffffff cmpne r8,#0x7fffffff beq CPDO_suf_extra cmp r1,r2 bne CPDO_adf_sCPDO_suf_s: subs r2,r7,r8 @ determine greater number bgt CPDO_suf_2nd @ first number is greater blt CPDO_suf_1st @ second number is greater cmp r3,r4 @ also mantissa is important cmpeq r5,r6 bhi CPDO_suf_2nd @ first number is greater beq CPDO_zeroCPDO_suf_1st: eor r1,r1,#0x80000000 @ second number is greater, invert sign mov r7,r8 rsb r2,r2,#0 cmp r2,#32 ble CPDO_suf_1st2 sub r2,r2,#32 cmp r2,#32 movgt r2,#32 mov r5,r3,lsr r2 mov r3,#0 b CPDO_suf_1st_subCPDO_suf_1st2: rsb r8,r2,#32 mov r5,r5,lsr r2 orr r5,r5,r3,lsl r8 mov r3,r3,lsr r2 @ 1. op normalizedCPDO_suf_1st_sub: subs r5,r6,r5 @ do subtraction sbc r3,r4,r3 b CPDO_suf_normCPDO_suf_2nd: cmp r2,#32 ble CPDO_suf_2nd2 sub r2,r2,#32 cmp r2,#32 movgt r2,#32 mov r6,r4,lsr r2 mov r4,#0 b CPDO_suf_2nd_subCPDO_suf_2nd2: rsb r8,r2,#32 mov r6,r6,lsr r2 orr r6,r6,r4,lsl r8 mov r4,r4,lsr r2 @ 2. op normalizedCPDO_suf_2nd_sub: subs r5,r5,r6 sbc r3,r3,r4 @ do subtractionCPDO_suf_norm: teq r3,#0 @ normalize 32bit moveq r3,r5 moveq r5,#0 subeq r7,r7,#32 cmp r3,#0x00010000 @ 16bit movcc r3,r3,lsl#16 orrcc r3,r3,r5,lsr#16 movcc r5,r5,lsl#16 subcc r7,r7,#16 cmp r3,#0x01000000 @ 8bit movcc r3,r3,lsl#8 orrcc r3,r3,r5,lsr#24 movcc r5,r5,lsl#8 subcc r7,r7,#8 cmp r3,#0x10000000 @ 4bit movcc r3,r3,lsl#4 orrcc r3,r3,r5,lsr#28 movcc r5,r5,lsl#4 subcc r7,r7,#4 cmp r3,#0x40000000 @ 2bit movcc r3,r3,lsl#2 orrcc r3,r3,r5,lsr#30 movcc r5,r5,lsl#2 subcc r7,r7,#2 cmp r3,#0x80000000 @ 1bit movcc r3,r3,lsl#1 orrcc r3,r3,r5,lsr#31 movcc r5,r5,lsl#1 subcc r7,r7,#1 cmp r7,#0xe0000000 ble CPDO_zero_1 stmia r0,{r1,r3,r5,r7} b fastfpe_nextCPDO_suf_extra: cmp r7,#0x7fffffff @ was it the 1st ? eorne r2,r2,#0x80000000 @ change sign, might have been INF bne CPDO_infnan_2 @ no it was the 2nd cmp r8,#0x7fffffff @ if 1st, 2nd too ? bne CPDO_infnan_1 @ no only 1st cmp r3,#0 cmpeq r4,#0 bne CPDO_nan_12 b CPDO_nan @ here is difference with adf !/*---------------------------------------------------------------------------*/ .globl CPDO_rsfCPDO_rsf: mov r3,r2 ldmia r1,{r2,r4,r6,r8} ldmia r3,{r1,r3,r5,r7} b CPDO_suf_l /*---------------------------------------------------------------------------*/ .globl CPDO_mufCPDO_muf: ldmia r1,{r1,r3,r5,r7} ldmia r2,{r2,r4,r6,r8} cmp r7,#0x7fffffff cmpne r8,#0x7fffffff beq CPDO_muf_extra eor r1,r1,r2 adds r8,r7,r8 bvs CPDO_zero_1 umull r7,r2,r3,r4 umull r14,r3,r6,r3 adds r7,r7,r3 @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14 adc r2,r2,#0 umull r4,r3,r5,r4 adds r14,r14,r4 @ r2|r7|r14 += #0|r3|r4 adcs r7,r7,r3 adc r2,r2,#0 umull r4,r3,r5,r6 adds r14,r14,r3 @ r2|r7|r14 += #0|#0|r3 adcs r7,r7,#0 adcs r2,r2,#0 bpl CPDO_muf_norm add r8,r8,#1 b CPDO_muf_end CPDO_muf_norm: adds r14,r14,r14 adcs r7,r7,r7 adcs r2,r2,r2CPDO_muf_end: cmp r8,#0x20000000 bge CPDO_inf cmp r8,#0xe0000000 ble CPDO_zero_1 stmia r0,{r1,r2,r7,r8} b fastfpe_nextCPDO_muf_extra: cmp r7,#0x7fffffff @ was it the first? bne CPDO_muf_extra_2nd @ no, so it was the second cmp r8,#0x7fffffff @ yes, second too? bne CPDO_muf_extra_1st @ no, only first orr r3,r3,r4 @ if both inf -> inf, otherwise nan eor r1,r1,r2 @ sign for the inf case b CPDO_infnan_1CPDO_muf_extra_1st: cmp r3,#0 @ is it a nan? bne CPDO_infnan_1 cmp r8,#0x80000000 @ is the second 0? beq CPDO_nan eor r1,r1,r2 @ correct sign for inf b CPDO_infCPDO_muf_extra_2nd: cmp r4,#0 @ is it a nan? bne CPDO_infnan_2 cmp r7,#0x80000000 @ is the first 0? beq CPDO_nan eor r1,r1,r2 @ correct sign for inf b CPDO_inf/*---------------------------------------------------------------------------*/ .globl CPDO_dvfCPDO_dvf: ldmia r1,{r1,r3,r5,r7} ldmia r2,{r2,r4,r6,r8}CPDO_dvf_l: cmp r7,#0x7fffffff cmpne r8,#0x7fffffff beq CPDO_dvf_extra cmp r8,#0x80000000 beq CPDO_dvf_by0 eor r1,r1,r2 cmp r7,#0x80000000 beq CPDO_zero_1 sub r8,r7,r8 mov r2,#0 mov r7,#1 cmp r3,r4 cmpeq r5,r6 bcs CPDO_dvf_loop_ sub r8,r8,#1CPDO_dvf_loop: adds r5,r5,r5 adcs r3,r3,r3 bcs CPDO_dvf_anywayCPDO_dvf_loop_: subs r5,r5,r6 sbcs r3,r3,r4 bcs CPDO_dvf_okay adds r5,r5,r6 adc r3,r3,r4 adds r7,r7,r7 adcs r2,r2,r2 bcc CPDO_dvf_loop b CPDO_dvf_endCPDO_dvf_anyway: adcs r7,r7,r7 adcs r2,r2,r2 bcs CPDO_dvf_end subs r5,r5,r6 sbc r3,r3,r4 b CPDO_dvf_loopCPDO_dvf_okay: adcs r7,r7,r7 adcs r2,r2,r2 bcc CPDO_dvf_loopCPDO_dvf_end: b CPDO_muf_endCPDO_dvf_by0: cmp R7,#0x80000000 beq CPDO_nan @ first also 0 -> nan eor r1,r1,r2 @ otherwise calculatesign for inf b CPDO_infCPDO_dvf_extra: cmp r7,#0x7fffffff @ was it the first? bne CPDO_dvf_extra_2nd @ no, so it was the second cmp r8,#0x7fffffff @ yes, second too? bne CPDO_dvf_extra_1st @ no, only first orrs r3,r3,r4 beq CPDO_nan @ if both inf -> create nan b CPDO_nan_12 @ otherwise keep nanCPDO_dvf_extra_1st: eor r1,r1,r2 @ correct sign for inf b CPDO_infnan_1CPDO_dvf_extra_2nd: cmp r4,#0 @ is it a nan? bne CPDO_infnan_2 eor r1,r1,r2 @ correct sign for zero b CPDO_zero_1/*---------------------------------------------------------------------------*/ .globl CPDO_rdfCPDO_rdf: mov r3,r2 ldmia r1,{r2,r4,r6,r8} ldmia r3,{r1,r3,r5,r7} b CPDO_dvf_l/*---------------------------------------------------------------------------*/ .globl CPDO_rmfCPDO_rmf: b fastfpe_next /*---------------------------------------------------------------------------*//*---------------------------------------------------------------------------*/ .globl CPDO_mvfCPDO_mvf: ldmia r2,{r1,r2,r3,r4} stmia r0,{r1,r2,r3,r4} b fastfpe_next/*---------------------------------------------------------------------------*/ .globl CPDO_mnfCPDO_mnf: ldmia r2,{r1,r2,r3,r4} eor r1,r1,#0x80000000 stmia r0,{r1,r2,r3,r4} b fastfpe_next/*---------------------------------------------------------------------------*/ .globl CPDO_absCPDO_abs: ldmia r2,{r1,r2,r3,r4} bic r1,r1,#0x80000000 stmia r0,{r1,r2,r3,r4} b fastfpe_next/*---------------------------------------------------------------------------*/ .globl CPDO_sqtCPDO_sqt: ldmia r2,{r1,r2,r3,r4} cmp r1,#0 bne CPDO_nan cmp r4,#0x7fffffff beq CPDO_store_1234 tst r4,r4,lsr#1 @carry=exponent bit 0 bcc CPDO_sqt_exponenteven adds r3,r3,r3 adcs r2,r2,r2 @carry is needed in loop!CPDO_sqt_exponenteven: mov r4,r4,asr #1 str r4,[r0,#12] mov r4,#0x80000000 mov r5,#0 sub r2,r2,#0x80000000 mov r8,#0x40000000 mov r14,#0x80000000 mov r1,#1 b CPDO_sqt_loop1_firstCPDO_sqt_loop1: adds r3,r3,r3 adcs r2,r2,r2CPDO_sqt_loop1_first: add r6,r4,r8,lsr r1 @r7 const = r5 bcs CPDO_sqt_loop1_1 cmp r2,r6 cmpeq r3,r5 @r5 for r7 bcc CPDO_sqt_loop1_0CPDO_sqt_loop1_1: orr r4,r4,r14,lsr r1 subs r3,r3,r5 @r5 for r7 sbc r2,r2,r6CPDO_sqt_loop1_0: add r1,r1,#1 cmp r1,#30 ble CPDO_sqt_loop1 adds r3,r3,r3 adcs r2,r2,r2 bcs CPDO_sqt_between_1 adds r7,r5,#0x80000000 adc r6,r4,#0 cmp r2,r6 cmpeq r3,r7 bcc CPDO_sqt_between_0CPDO_sqt_between_1: orr r4,r4,#0x00000001 subs r3,r3,r5 sbc r2,r2,r4 subs r3,r3,#0x80000000 sbc r2,r2,#0CPDO_sqt_between_0: mov r1,#0CPDO_sqt_loop2: adds r3,r3,r3 adcs r2,r2,r2 bcs CPDO_sqt_loop2_1 adds r7,r5,r8,lsr r1 adc r6,r4,#0 cmp r2,r6 cmpeq r3,r7 bcc CPDO_sqt_loop2_0CPDO_sqt_loop2_1: orr r5,r5,r14,lsr r1 subs r3,r3,r5 sbc r2,r2,r4 subs r3,r3,r8,lsr r1 sbc r2,r2,#0CPDO_sqt_loop2_0: add r1,r1,#1 cmp r1,#30 ble CPDO_sqt_loop2 adds r3,r3,r3 adcs r2,r2,r2 bcs CPDO_sqt_after_1 cmp r2,r6 cmpeq r3,r7 bcc CPDO_sqt_after_0CPDO_sqt_after_1: orr r5,r5,#0x00000001CPDO_sqt_after_0: mov r1,#0 stmia r0,{r1,r4,r5} b fastfpe_next/*---------------------------------------------------------------------------*/ .globl CPDO_rndCPDO_rnd: ldmia r2,{r1,r2,r3,r5} bl CPDO_rnd_coreCPDO_rnd_store: stmia r0,{r1,r2,r3,r5} b fastfpe_next /*---------------------------------------------------------------------------*/ .globl CPDO_rnd_coreCPDO_rnd_core: and r4,r4,#0x00000060 add pc,pc,r4,lsr#3 mov r0,r0 b CPDO_rnd_N b CPDO_rnd_P b CPDO_rnd_M b CPDO_rnd_Z CPDO_rnd_N: cmp r5,#-1 blt CPDO_rnd_zero cmp r5,#63 movge pc,r14 mov r4,#0x40000000 cmp r5,#31 bge CPDO_rnd_N_2 adds r2,r2,r4,lsr r5 bcc CPDO_rnd_end b CPDO_rnd_end_normCPDO_rnd_N_2:CPDO_rnd_P_2: sub r6,r5,#32 adds r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly adcs r2,r2,#0 bcc CPDO_rnd_end b CPDO_rnd_end_normCPDO_rnd_P: tst r1,#0x80000000 bne CPDO_rnd_M_entryCPDO_rnd_P_entry: cmp r5,#0 blt CPDO_rnd_P_small cmp r5,#63 movge pc,r14 mov r4,#0x7fffffff cmp r5,#32 bge CPDO_rnd_P_2 adds r3,r3,#0xffffffff adcs r2,r2,r4,lsr r5 bcc CPDO_rnd_end b CPDO_rnd_end_normCPDO_rnd_P_small: cmp r5,#0x80000000 moveq pc,r14 b CPDO_rnd_oneCPDO_rnd_M: tst r1,#0x80000000 bne CPDO_rnd_P_entryCPDO_rnd_M_entry: cmp r5,#0 blt CPDO_rnd_zero cmp r5,#63 movge pc,r14 b CPDO_rnd_end CPDO_rnd_Z: cmp r5,#0 blt CPDO_rnd_zero cmp r5,#63 movge pc,r14 b CPDO_rnd_endCPDO_rnd_end_norm: add r5,r5,#1 movs r2,r2,rrx mov r3,r3,rrxCPDO_rnd_end: rsbs r4,r5,#31 bmi CPDO_rnd_end_2 mov r3,#0 mov r2,r2,lsr r4 mov r2,r2,lsl r4 mov pc,r14CPDO_rnd_end_2: rsb r4,r5,#63 mov r3,r3,lsr r4 mov r3,r3,lsl r4 mov pc,r14CPDO_rnd_one: mov r2,#0x80000000 mov r3,#0 mov r5,#0 mov pc,r14 CPDO_rnd_zero: mov r1,#0 mov r2,#0 mov r3,#0 mov r5,#0x80000000 mov pc,r14/*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -