📄 suppasm.s
字号:
STRGEB tmp1, [dst, #-1]! LDRGTB tmp1, [src, #-1]! STRGTB tmp1, [dst, #-1]! SUBS n, n, tmp3 ; check number to go BLT Down_TrailingBytes ; less than 4 bytes ANDS tmp3, src, #3 BEQ Down_SrcDstAligned ; coaligned case ; The source is not coaligned with the destination, ; the destination IS currently word aligned.Down_SrcUnaligned BIC src, src, #3 ; tmp3 holds extra! LDR tmp1, [src] ; 1-3 useful bytes CMP tmp3, #2 BLT Down_OneByte ; one byte in tmp1 BEQ Down_TwoBytes ; two bytes in tmp1; The last three source bytes are in tmp1, one byte must; come from the previous source word. At least four bytes; more must be stored. Check first to see if there are a; sufficient number of bytes to go to justify using stm/ldm; instructions.Down_ThreeBytes CMP n, #16-4 ; at least 16 bytes? BLT %F1 ; no SUB n, n, #16-4 ; (n+16) bytes to go ; form a stack frame and save registers STMFD sp!, {v1, v2, lr} ; loop doing 32 bytes at a time. There are currently ; three useful bytes in tmp1 (a4).0 MOV lr, tmp1, $SHA #8 ; last three bytes LDMDB src!, {tmp1, v1, v2, tmp3} ORR lr, lr, tmp3, $SLA #24 ; word 4 MOV tmp3, tmp3, $SHA #8 ORR tmp3, tmp3, v2, $SLA #24 ; word 3 MOV v2, v2, $SHA #8 ORR v2, v2, v1, $SLA #24 ; word 2 MOV v1, v1, $SHA #8 ORR v1, v1, tmp1, $SLA #24 ; word 1 STMDB dst!, {v1, v2, tmp3, lr} SUBS n, n, #16 BGE %B0 ; Reload registers LDMFD sp!, {v1, v2, lr} ADDS n, n, #16-4 ; check for at least 4 BLT %F2 ; < 4 bytes1 MOV tmp3, tmp1, $SHA #8 ; last three bytes LDR tmp1, [src, #-4]! ; previous four bytes ORR tmp3, tmp3, tmp1, $SLA #24 STR tmp3, [dst, #-4]! SUBS n, n, #4 BGE %B1 ; tmp1 contains three bytes ; Less than four bytes to go - readjust the src ; address.2 ADD src, src, #3 B Down_TrailingBytes; The last two source bytes are in tmp1, two bytes must; come from the previous source word. At least four bytes; more must be stored.Down_TwoBytes CMP n, #16-4 ; at least 16 bytes? BLT %F1 ; no SUB n, n, #16-4 ; (n+16) bytes to go ; form a stack frame and save registers STMFD sp!, {v1, v2, lr} ; loop doing 32 bytes at a time. There are currently ; two useful bytes in tmp1 (a4).0 MOV lr, tmp1, $SHA #16 ; last two bytes LDMDB src!, {tmp1, v1, v2, tmp3} ORR lr, lr, tmp3, $SLA #16 ; word 4 MOV tmp3, tmp3, $SHA #16 ORR tmp3, tmp3, v2, $SLA #16 ; word 3 MOV v2, v2, $SHA #16 ORR v2, v2, v1, $SLA #16 ; word 2 MOV v1, v1, $SHA #16 ORR v1, v1, tmp1, $SLA #16 ; word 1 STMDB dst!, {v1, v2, tmp3, lr} SUBS n, n, #16 BGE %B0 ; Reload registers LDMFD sp!, {v1, v2, lr} ADDS n, n, #16-4 ; check for at least 4 BLT %F2 ; < 4 bytes1 MOV tmp3, tmp1, $SHA #16 ; last two bytes LDR tmp1, [src, #-4]! ; previous four bytes ORR tmp3, tmp3, tmp1, $SLA #16 STR tmp3, [dst, #-4]! SUBS n, n, #4 BGE %B1 ; tmp1 contains two bytes ; Less than four bytes to go - readjust the src ; address.2 ADD src, src, #2 B Down_TrailingBytes; The last source byte is in tmp1, three bytes must; come from the previous source word. At least four bytes; more must be stored.Down_OneByte CMP n, #16-4 ; at least 16 bytes? BLT %F1 ; no SUB n, n, #16-4 ; (n+16) bytes to go ; form a stack frame and save registers STMFD sp!, {v1, v2, lr} ; loop doing 32 bytes at a time. There is currently ; one useful byte in tmp1 (a4).0 MOV lr, tmp1, $SHA #24 ; last byte LDMDB src!, {tmp1, v1, v2, tmp3} ORR lr, lr, tmp3, $SLA #8 ; word 4 MOV tmp3, tmp3, $SHA #24 ORR tmp3, tmp3, v2, $SLA #8 ; word 3 MOV v2, v2, $SHA #24 ORR v2, v2, v1, $SLA #8 ; word 2 MOV v1, v1, $SHA #24 ORR v1, v1, tmp1, $SLA #8 ; word 1 STMDB dst!, {v1, v2, tmp3, lr} SUBS n, n, #16 BGE %B0 ; Reload registers LDMFD sp!, {v1, v2, lr} ADDS n, n, #16-4 ; check for at least 4 BLT %F2 ; < 4 bytes1 MOV tmp3, tmp1, $SHA #24 ; last byte LDR tmp1, [src, #-4]! ; previous four bytes ORR tmp3, tmp3, tmp1, $SLA #8 STR tmp3, [dst, #-4]! SUBS n, n, #4 BGE %B1 ; tmp1 contains one byte ; Less than four bytes to go - one already in tmp3.2 ADD src, src, #1 B Down_TrailingBytes | ; old, slow memcpy__rt_memcpy ; a1 = dst address ; a2 = src address ; a3 = byte count. ; ; A very slow version of memcpy. Its only merit is that it is quite ; small. ; CMP a3,#0 MOVEQ pc,lr CMP a2,a1 BLO CopyDown MOVEQ pc,lr MOV ip,a1CopyUpLoop LDRB a4,[a2],#1 STRB a4,[ip],#1 SUBS a3,a3,#1 BNE CopyUpLoopmemcpyExit MOV pc,lrCopyDown ADD a2,a2,a3 ADD a1,a1,a3CopyDownLoop LDRB a4,[a2,#-1]! STRB a4,[a1,#-1]! SUBS a3,a3,#1 BNE CopyDownLoop BAL memcpyExit ] EXPORT __rt_udiv__rt_udiv ; Signed divide of a2 by a1, returns quotient in a1, remainder in a2 ; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2 ; Destroys a3, a4 and ip MOVS a3,a1 BEQ __division_by_zero MOV a4,#0 MOV ip,#0x80000000 CMP a2,# ip MOVLO ip,a201 CMP ip,a3,ASL #0 BLS u_shifted0mod8 CMP ip,a3,ASL #1 BLS u_shifted1mod8 CMP ip,a3,ASL #2 BLS u_shifted2mod8 CMP ip,a3,ASL #3 BLS u_shifted3mod8 CMP ip,a3,ASL #4 BLS u_shifted4mod8 CMP ip,a3,ASL #5 BLS u_shifted5mod8 CMP ip,a3,ASL #6 BLS u_shifted6mod8 CMP ip,a3,ASL #7 MOVHI a3,a3,ASL #8 BHI %BT0102u_shifted7mod8 CMP a2,a3,ASL #7 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #7u_shifted6mod8 CMP a2,a3,ASL #6 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #6u_shifted5mod8 CMP a2,a3,ASL #5 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #5u_shifted4mod8 CMP a2,a3,ASL #4 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #4u_shifted3mod8 CMP a2,a3,ASL #3 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #3u_shifted2mod8 CMP a2,a3,ASL #2 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #2u_shifted1mod8 CMP a2,a3,ASL #1 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #1u_shifted0mod8 CMP a2,a3,ASL #0 ADC a4,a4,a4 SUBHS a2,a2,a3,ASL #0 CMP a1,a3,LSR #1 MOVLS a3,a3,LSR #8 BLS %BT02 MOV a1,a4 MOV pc,lr__division_by_zero ; Currently we do not deal with division by zero in a nice way MOV a1,#0 MOV a2,#0 MOV pc,lr EXPORT __rt_udiv10__rt_udiv10 ROUT SUB a2, a1, #10 SUB a1, a1, a1, lsr #2 ADD a1, a1, a1, lsr #4 ADD a1, a1, a1, lsr #8 ADD a1, a1, a1, lsr #16 MOV a1, a1, lsr #3 ADD a3, a1, a1, asl #2 SUBS a2, a2, a3, asl #1 ADDPL a1, a1, #1 ADDMI a2, a2, #10 MOV pc, lr EXPORT __rt_memcmp__rt_memcmp ROUT MOV a4, a1 MOVS a1, a3 MOVEQ pc, lr0 LDRB a1, [a2], #1 LDRB ip, [a4], #1 SUBS a1, a1, ip MOVNE pc, lr SUBS a3, a3, #1 BNE %0 MOV pc, lr EXPORT __rt_strlen__rt_strlen ROUT MOV a2, a1 MOV a1, #00 LDRB a3, [a2], #1 CMP a3, #0 MOVEQ pc, lr ADD a1, a1, #1 B %0 ;; The following routines are currently only needed for the Fusion;; TCP/IP stack and Ethernet drivers, so don't include them if we;; don't have to IF ETHERNET_SUPPORTED /= 0 EXPORT __rt_divtest__rt_divtest ROUT CMPS a1, #0 MOVNE pc, lr;;;; Fall through to...;;__rt_div0 ROUT MOV a1, #angel_SWIreason_ReportException LDR a2, =ADP_Stopped_DivisionByZero DCD angel_SWI_ARM ; if we ever continue from this SWI, then report this and die ADR a1, div0msg B __rt_asm_fatalerrordiv0msg DCB "Divide by zero\n" ALIGN ENDIF ; ETHERNET_SUPPORTED /= 0 ;;;; __rt_memXXX routines - small but inefficient;; EXPORT __rt_memset__rt_memset ROUT ADD a3, a3, #1 MOV a4, a10 SUBS a3, a3, #1 MOVEQ pc, lr STRB a2, [a4], #1 B %0 EXPORT __rt_strcmp__rt_strcmp ROUT MOV ip, a10 LDRB a3, [ip], #1 LDRB a4, [a2], #1 SUBS a1, a3, a4 MOVNE pc, lr CMP a3, #0 CMPNE a4, #0 BNE %0 MOV pc, lr EXPORT __rt_strncmp__rt_strncmp ROUT MOV ip, a1 MOVS a1, a3 MOVEQ pc, lr STR lr, [sp, #-4]!0 LDRB lr, [ip], #1 LDRB a4, [a2], #1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -