summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@gmail.com>2013-11-25 14:55:11 -0500
committerErik Schnetter <schnetter@gmail.com>2013-11-25 14:55:11 -0500
commit36f7de41c871def89b0245748d29ac2c2dae0609 (patch)
tree45fcc7cfa448f004494949a8dcfc44435bbcaee3
parent942b1fa0654668576d3990c9c3ad721aaf703f7e (diff)
downloadvecmathlib-36f7de41c871def89b0245748d29ac2c2dae0609.zip
vecmathlib-36f7de41c871def89b0245748d29ac2c2dae0609.tar.gz
Correct clz implementation
-rw-r--r--vec_pseudo.h32
1 files changed, 20 insertions, 12 deletions
diff --git a/vec_pseudo.h b/vec_pseudo.h
index 2424d40..a79e072 100644
--- a/vec_pseudo.h
+++ b/vec_pseudo.h
@@ -366,18 +366,26 @@ namespace vecmathlib {
{
intvec_t res;
#if defined __clang__ || defined __gcc__
- if (sizeof(int_t) == sizeof(long long)) {
- for (int d=0; d<size; ++d) res.v[d] = __builtin_clzll(v[d]);
- } else if (sizeof(int_t) == sizeof(long)) {
- for (int d=0; d<size; ++d) res.v[d] = __builtin_clzl(v[d]);
- } else if (sizeof(int_t) == sizeof(int)) {
- for (int d=0; d<size; ++d) res.v[d] = __builtin_clz(v[d]);
- } else if (sizeof(int_t) <= sizeof(short)) {
- for (int d=0; d<size; ++d)
- res.v[d] =
- CHAR_BIT * (sizeof(short) - sizeof(int_t)) + __builtin_clzs(v[d]);
- } else {
- __builtin_unreachable();
+ for (int d=0; d<size; ++d) {
+ if (v[d] == 0) {
+ res.v[d] = CHAR_BIT * sizeof v[d];
+ } else {
+ if (sizeof v[d] == sizeof(long long)) {
+ res.v[d] = __builtin_clzll(v[d]);
+ } else if (sizeof v[d] == sizeof(long)) {
+ res.v[d] = __builtin_clzl(v[d]);
+ } else if (sizeof v[d] == sizeof(int)) {
+ res.v[d] = __builtin_clz(v[d]);
+ } else if (sizeof v[d] == sizeof(short)) {
+ res.v[d] = __builtin_clzs(v[d]);
+ } else if (sizeof v[d] == sizeof(char)) {
+ res.v[d] =
+ __builtin_clzs((unsigned short)(unsigned char)v[d]) -
+ CHAR_BIT * (sizeof(short) - sizeof(char));
+ } else {
+ __builtin_unreachable();
+ }
+ }
}
#else
res = MF::vml_clz(*this);
OpenPOWER on IntegriCloud