12d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/* ===-- clzsi2.c - Implement __clzsi2 -------------------------------------=== 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * The LLVM Compiler Infrastructure 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * This file is dual licensed under the MIT and the University of Illinois Open 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * Source Licenses. See LICENSE.TXT for details. 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * ===----------------------------------------------------------------------=== 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * This file implements count leading zeros for 32bit arguments. 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * ===----------------------------------------------------------------------=== 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines */ 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "../assembly.h" 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines .syntax unified 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines .text 185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#if __ARM_ARCH_ISA_THUMB == 2 195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines .thumb 205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif 215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines .p2align 2 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesDEFINE_COMPILERRT_FUNCTION(__clzsi2) 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifdef __ARM_FEATURE_CLZ 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines clz r0, r0 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines JMP(lr) 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#else 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines /* Assumption: n != 0 */ 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 302d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines /* 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r0: n 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r1: count of leading zeros in n + 1 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r2: scratch register for shifted r0 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines */ 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines mov r1, 1 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines /* 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * Basic block: 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * if ((r0 >> SHIFT) == 0) 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r1 += SHIFT; 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * else 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r0 >>= SHIFT; 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * for descending powers of two as SHIFT. 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines */ 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#define BLOCK(shift) \ 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines lsrs r2, r0, shift; \ 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines movne r0, r2; \ 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines addeq r1, shift \ 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines BLOCK(16) 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines BLOCK(8) 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines BLOCK(4) 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines BLOCK(2) 552d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 562d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines /* 572d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * The basic block invariants at this point are (r0 >> 2) == 0 and 582d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1. 592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 602d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1) 612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * ---+----------------+----------------+------------+-------------- 622d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 1 | 1 | 0 | 0 | 1 632d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 2 | 0 | 1 | -1 | 0 642d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 3 | 0 | 1 | -1 | 0 652d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * 662d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * The r1's initial value of 1 compensates for the 1 here. 672d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines */ 682d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines sub r0, r1, r0, lsr #1 692d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 702d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines JMP(lr) 712d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif // __ARM_FEATURE_CLZ 722d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen HinesEND_COMPILERRT_FUNCTION(__clzsi2) 73