udivsi3.S revision 5d71de26cedae3dafc17449fe0182045c0bd20e8
14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*===-- udivsi3.S - 32-bit unsigned integer divide ------------------------===// 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * The LLVM Compiler Infrastructure 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * This file is dual licensed under the MIT and the University of Illinois Open 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Source Licenses. See LICENSE.TXT for details. 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *===----------------------------------------------------------------------===// 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * This file implements the __udivsi3 (32-bit unsigned integer divide) 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * function for the ARM 32-bit architecture. 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *===----------------------------------------------------------------------===*/ 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "../assembly.h" 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project .syntax unified 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project .text 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project .p2align 2 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectDEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3) 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectDEFINE_COMPILERRT_FUNCTION(__udivsi3) 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if __ARM_ARCH_EXT_IDIV__ 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project tst r1, r1 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project beq LOCAL_LABEL(divby0) 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mov r3, r0 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project udiv r0, r3, r1 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mls r1, r0, r1, r3 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bx lr 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#else 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r1, #1 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bcc LOCAL_LABEL(divby0) 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project JMPc(lr, eq) 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r0, r1 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project movcc r0, #0 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project JMPc(lr, cc) 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Implement division using binary long division algorithm. 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * r0 is the numerator, r1 the denominator. 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * The code before JMP computes the correct shift I, so that 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * r0 and (r1 << I) have the highest bit set in the same position. 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * At the time of JMP, ip := .Ldiv0block - 12 * I. 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * This depends on the fixed instruction size of block. 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * block(shift) implements the test-and-update-quotient core. 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * It assumes (r0 << shift) can be computed without overflow and 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * that (r0 << shift) < 2 * r1. The quotient is stored in r3. 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project# ifdef __ARM_FEATURE_CLZ 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project clz ip, r0 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project clz r3, r1 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* r0 >= r1 implies clz(r0) <= clz(r1), so ip <= r3. */ 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sub r3, r3, ip 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project adr ip, LOCAL_LABEL(div0block) 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sub ip, ip, r3, lsl #2 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sub ip, ip, r3, lsl #3 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mov r3, #0 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bx ip 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project# else 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mov r2, r0 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project adr ip, LOCAL_LABEL(div0block) 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project lsr r3, r2, #16 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r3, r1 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project movhs r2, r3 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project subhs ip, ip, #(16 * 12) 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project lsr r3, r2, #8 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r3, r1 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project movhs r2, r3 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project subhs ip, ip, #(8 * 12) 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project lsr r3, r2, #4 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r3, r1 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project movhs r2, r3 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project subhs ip, #(4 * 12) 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project lsr r3, r2, #2 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r3, r1 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project movhs r2, r3 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project subhs ip, ip, #(2 * 12) 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Last block, no need to update r2 or r3. */ 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r1, r2, lsr #1 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project subls ip, ip, #(1 * 12) 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mov r3, #0 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project JMP(ip) 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project# endif 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define IMM # 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define block(shift) \ 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project cmp r0, r1, lsl IMM shift; \ 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project addhs r3, r3, IMM (1 << shift); \ 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project subhs r0, r0, r1, lsl IMM shift 101 102 block(31) 103 block(30) 104 block(29) 105 block(28) 106 block(27) 107 block(26) 108 block(25) 109 block(24) 110 block(23) 111 block(22) 112 block(21) 113 block(20) 114 block(19) 115 block(18) 116 block(17) 117 block(16) 118 block(15) 119 block(14) 120 block(13) 121 block(12) 122 block(11) 123 block(10) 124 block(9) 125 block(8) 126 block(7) 127 block(6) 128 block(5) 129 block(4) 130 block(3) 131 block(2) 132 block(1) 133LOCAL_LABEL(div0block): 134 block(0) 135 136 mov r0, r3 137 JMP(lr) 138#endif /* __ARM_ARCH_EXT_IDIV__ */ 139 140LOCAL_LABEL(divby0): 141 mov r0, #0 142#ifdef __ARM_EABI__ 143 b __aeabi_idiv0 144#else 145 JMP(lr) 146#endif 147 148END_COMPILERRT_FUNCTION(__udivsi3) 149