brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.7 KiB · 5d86fe4 Raw
67 lines · plain
1//===-- clzsi2.c - Implement __clzsi2 -------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements count leading zeros for 32bit arguments.10//11//===----------------------------------------------------------------------===//12 13#include "../assembly.h"14 15	.syntax unified16	.text17	DEFINE_CODE_STATE18 19	.p2align	220DEFINE_COMPILERRT_FUNCTION(__clzsi2)21#ifdef __ARM_FEATURE_CLZ22	clz	r0, r023	JMP(lr)24#else25	// Assumption: n != 026 27	// r0: n28	// r1: count of leading zeros in n + 129	// r2: scratch register for shifted r030	mov	r1, 131 32	// Basic block:33	// if ((r0 >> SHIFT) == 0)34	//   r1 += SHIFT;35	// else36	//   r0 >>= SHIFT;37	// for descending powers of two as SHIFT.38 39#define BLOCK(shift) \40	lsrs	r2, r0, shift; \41	movne	r0, r2; \42	addeq	r1, shift \43 44	BLOCK(16)45	BLOCK(8)46	BLOCK(4)47	BLOCK(2)48 49	// The basic block invariants at this point are (r0 >> 2) == 0 and50	// r0 != 0. This means 1 <= r0 <= 3 and 0 <= (r0 >> 1) <= 1.51	//52	// r0 | (r0 >> 1) == 0 | (r0 >> 1) == 1 | -(r0 >> 1) | 1 - (r0 >> 1)53	// ---+----------------+----------------+------------+--------------54	// 1  | 1              | 0              | 0          | 155	// 2  | 0              | 1              | -1         | 056	// 3  | 0              | 1              | -1         | 057	//58	// The r1's initial value of 1 compensates for the 1 here.59	sub	r0, r1, r0, lsr #160 61	JMP(lr)62#endif // __ARM_FEATURE_CLZ63END_COMPILERRT_FUNCTION(__clzsi2)64 65NO_EXEC_STACK_DIRECTIVE66 67