; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; ; > Sources.CSupport EXPORT |__rt_sdiv| EXPORT |__rt_udiv| EXPORT |memcpy| EXPORT |memset| |x$divide| |__rt_sdiv| |_kernel_sdiv| ; Signed divide of a2 by a1: returns quotient in a1, remainder in a2 ; Quotient is truncated (rounded towards zero). ; Sign of remainder = sign of dividend. ; Destroys a3, a4 and ip ; Negates dividend and divisor, then does an unsigned divide; signs ; get sorted out again at the end. ; Code mostly as for udiv, except that the justification part is slightly ; simplified by knowledge that the dividend is in the range [0..#x80000000] ; (one register may be gained thereby). MOVS ip, a1 BEQ dividebyzero RSBMI a1, a1, #0 ; absolute value of divisor EOR ip, ip, a2 ANDS a4, a2, #&80000000 ORR ip, a4, ip, LSR #1 ; ip bit 31 sign of dividend (= sign of remainder) ; bit 30 sign of dividend EOR sign of divisor (= sign of quotient) RSBNE a2, a2, #0 ; absolute value of dividend MOV a3, a1 MOV a4, #0 s_loop CMP a2, a3, ASL #0 BLS s_shifted0mod8 CMP a2, a3, ASL #1 BLS s_shifted1mod8 CMP a2, a3, ASL #2 BLS s_shifted2mod8 CMP a2, a3, ASL #3 BLS s_shifted3mod8 CMP a2, a3, ASL #4 BLS s_shifted4mod8 CMP a2, a3, ASL #5 BLS s_shifted5mod8 CMP a2, a3, ASL #6 BLS s_shifted6mod8 CMP a2, a3, ASL #7 MOVHI a3, a3, ASL #8 BHI s_loop s_loop2 CMP a2, a3, ASL #7 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #7 CMP a2, a3, ASL #6 s_shifted6mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #6 CMP a2, a3, ASL #5 s_shifted5mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #5 CMP a2, a3, ASL #4 s_shifted4mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #4 CMP a2, a3, ASL #3 s_shifted3mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #3 CMP a2, a3, ASL #2 s_shifted2mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #2 CMP a2, a3, ASL #1 s_shifted1mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #1 CMP a2, a3, ASL #0 s_shifted0mod8 ADC a4, a4, a4 SUBHS a2, a2, a3, ASL #0 CMP a1, a3, LSR #1 MOVLS a3, a3, LSR #8 BLS s_loop2 MOV a1, a4 TST ip, #&40000000 RSBNE a1, a1, #0 TST ip, #&80000000 RSBNE a2, a2, #0 MOV pc, r14 ; Signed remainder of a2 by a1: returns remainder in a1 |_kernel_srem| STR r14, [sp, #-4]! BL |_kernel_sdiv| MOV a1, a2 LDR pc, [sp], #4 |x$udivide| |__rt_udiv| |_kernel_udiv| ; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2 ; Destroys a3 and ip MOV a3, #0 RSBS ip, a1, a2, LSR #3 BCC u_sh2 RSBS ip, a1, a2, LSR #8 BCC u_sh7 MOV a1, a1, LSL #8 ORR a3, a3, #&FF000000 RSBS ip, a1, a2, LSR #4 BCC u_sh3 RSBS ip, a1, a2, LSR #8 BCC u_sh7 MOV a1, a1, LSL #8 ORR a3, a3, #&00FF0000 RSBS ip, a1, a2, LSR #8 MOVCS a1, a1, LSL #8 ORRCS a3, a3, #&0000FF00 RSBS ip, a1, a2, LSR #4 BCC u_sh3 RSBS ip, a1, #0 BCS dividebyzero u_loop MOVCS a1, a1, LSR #8 u_sh7 RSBS ip, a1, a2, LSR #7 SUBCS a2, a2, a1, LSL #7 ADC a3, a3, a3 u_sh6 RSBS ip, a1, a2, LSR #6 SUBCS a2, a2, a1, LSL #6 ADC a3, a3, a3 u_sh5 RSBS ip, a1, a2, LSR #5 SUBCS a2, a2, a1, LSL #5 ADC a3, a3, a3 u_sh4 RSBS ip, a1, a2, LSR #4 SUBCS a2, a2, a1, LSL #4 ADC a3, a3, a3 u_sh3 RSBS ip, a1, a2, LSR #3 SUBCS a2, a2, a1, LSL #3 ADC a3, a3, a3 u_sh2 RSBS ip, a1, a2, LSR #2 SUBCS a2, a2, a1, LSL #2 ADC a3, a3, a3 u_sh1 RSBS ip, a1, a2, LSR #1 SUBCS a2, a2, a1, LSL #1 ADC a3, a3, a3 u_sh0 RSBS ip, a1, a2 SUBCS a2, a2, a1 ADCS a3, a3, a3 BCS u_loop MOV a1, a3 MOV pc, r14 |memcpy| ; extern void *memcpy(void *a1, const void *a2, size_t a3) TEQ a3, #0 MOVNE ip, a1 mc_0 LDRNEB a4, [a2], #1 STRNEB a4, [ip], #1 SUBNES a3, a3, #1 BNE mc_0 MOV pc, lr |memset| ; extern void *memset(void *a1, int a2, size_t a3) TEQ a3, #0 MOVNE ip, a1 ms_0 STRNEB a2, [ip], #1 SUBNES a3, a3, #1 BNE ms_0 MOV pc, lr END