Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add __ffssi2 implementation to compiler-rt builtins
Summary: During MIPS implementation work for FreeBSD, John Baldwin (jhb@FreeBSD.org) found that gcc 6.x emits calls to __ffssi2() when compiling libc and some userland programs in the base system. Add it to compiler-rt's builtins, based off of the existing __ffsdi2() implementation. Also update the CMake files and add a test case. Reviewers: howard.hinnant, weimingz, rengolin, compnerd Reviewed By: weimingz Subscribers: dberris, mgorny, llvm-commits, emaste Differential Revision: https://reviews.llvm.org/D31721 llvm-svn: 299675
- Loading branch information
1 parent
2b622b1
commit 01220bf
Showing
4 changed files
with
88 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,7 @@ set(GENERIC_SOURCES | |
extendsfdf2.c | ||
extendhfsf2.c | ||
ffsdi2.c | ||
ffssi2.c | ||
ffsti2.c | ||
fixdfdi.c | ||
fixdfsi.c | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* ===-- ffssi2.c - Implement __ffssi2 -------------------------------------=== | ||
* | ||
* The LLVM Compiler Infrastructure | ||
* | ||
* This file is dual licensed under the MIT and the University of Illinois Open | ||
* Source Licenses. See LICENSE.TXT for details. | ||
* | ||
* ===----------------------------------------------------------------------=== | ||
* | ||
* This file implements __ffssi2 for the compiler_rt library. | ||
* | ||
* ===----------------------------------------------------------------------=== | ||
*/ | ||
|
||
#include "int_lib.h" | ||
|
||
/* Returns: the index of the least significant 1-bit in a, or | ||
* the value zero if a is zero. The least significant bit is index one. | ||
*/ | ||
|
||
COMPILER_RT_ABI si_int | ||
__ffssi2(si_int a) | ||
{ | ||
if (a == 0) | ||
{ | ||
return 0; | ||
} | ||
return __builtin_ctz(a) + 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// RUN: %clang_builtins %s %librt -o %t && %run %t | ||
//===-- ffssi2_test.c - Test __ffssi2 -------------------------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is dual licensed under the MIT and the University of Illinois Open | ||
// Source Licenses. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file tests __ffssi2 for the compiler_rt library. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "int_lib.h" | ||
#include <stdio.h> | ||
|
||
// Returns: the index of the least significant 1-bit in a, or | ||
// the value zero if a is zero. The least significant bit is index one. | ||
|
||
COMPILER_RT_ABI si_int __ffssi2(si_int a); | ||
|
||
int test__ffssi2(si_int a, si_int expected) | ||
{ | ||
si_int x = __ffssi2(a); | ||
if (x != expected) | ||
printf("error in __ffssi2(0x%X) = %d, expected %d\n", a, x, expected); | ||
return x != expected; | ||
} | ||
|
||
int main() | ||
{ | ||
if (test__ffssi2(0x00000000, 0)) | ||
return 1; | ||
if (test__ffssi2(0x00000001, 1)) | ||
return 1; | ||
if (test__ffssi2(0x00000002, 2)) | ||
return 1; | ||
if (test__ffssi2(0x00000003, 1)) | ||
return 1; | ||
if (test__ffssi2(0x00000004, 3)) | ||
return 1; | ||
if (test__ffssi2(0x00000005, 1)) | ||
return 1; | ||
if (test__ffssi2(0x0000000A, 2)) | ||
return 1; | ||
if (test__ffssi2(0x10000000, 29)) | ||
return 1; | ||
if (test__ffssi2(0x20000000, 30)) | ||
return 1; | ||
if (test__ffssi2(0x60000000, 30)) | ||
return 1; | ||
if (test__ffssi2(0x80000000u, 32)) | ||
return 1; | ||
|
||
return 0; | ||
} |