[PATCH 1/7] bits: add helpers for zero & sign-extension

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Zero & sign-extensions are relatively common operations
which are currently open-coded at each use.

Define helpers for doing these operations.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 bits.h   | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib.h    |  1 +
 symbol.h |  8 ++++++++
 3 files changed, 70 insertions(+)
 create mode 100644 bits.h

diff --git a/bits.h b/bits.h
new file mode 100644
index 000000000..c0dc952ea
--- /dev/null
+++ b/bits.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Helper functions for manipulation & testing of integer values
+ * like zero or sign-extensions.
+ *
+ * Copyright (C) 2017 Luc Van Oostenryck
+ *
+ */
+
+#ifndef BITS_H
+#define BITS_H
+
+static inline unsigned long long sign_bit(unsigned size)
+{
+	return 1ULL << (size - 1);
+}
+
+static inline unsigned long long sign_mask(unsigned size)
+{
+	unsigned long long sbit = sign_bit(size);
+	return sbit - 1;
+}
+
+static inline unsigned long long bits_mask(unsigned size)
+{
+	unsigned long long sbit = sign_bit(size);
+	return sbit | (sbit - 1);
+}
+
+
+static inline long long zero_extend(long long val, unsigned size)
+{
+	return val & bits_mask(size);
+}
+
+static inline long long sign_extend(long long val, unsigned size)
+{
+	if (val & sign_bit(size))
+		val |= ~sign_mask(size);
+	return val;
+}
+
+///
+// sign extend @val but only if exactly representable
+static inline long long sign_extend_safe(long long val, unsigned size)
+{
+	unsigned long long mask = bits_mask(size);
+	if (!(val & ~mask))
+		val = sign_extend(val, size);
+	return val;
+}
+
+static inline long long bits_extend(long long val, unsigned size, int is_signed)
+{
+	val = zero_extend(val, size);
+	if (is_signed)
+		val = sign_extend(val, size);
+	return val;
+}
+
+#endif
diff --git a/lib.h b/lib.h
index 7362111cd..3cd8560a5 100644
--- a/lib.h
+++ b/lib.h
@@ -34,6 +34,7 @@
 #include "compat.h"
 #include "ptrlist.h"
 #include "utils.h"
+#include "bits.h"
 
 #define DO_STRINGIFY(x) #x
 #define STRINGIFY(x) DO_STRINGIFY(x)
diff --git a/symbol.h b/symbol.h
index 6b891edd6..1cad6d052 100644
--- a/symbol.h
+++ b/symbol.h
@@ -453,6 +453,14 @@ static inline int get_sym_type(struct symbol *type)
 	return type->type;
 }
 
+static inline long long extend_value(long long val, struct symbol *ctype)
+{
+	int is_signed = !(ctype->ctype.modifiers & MOD_UNSIGNED);
+	unsigned size = ctype->bit_size;
+
+	return bits_extend(val, size, is_signed);
+}
+
 static inline struct symbol *lookup_keyword(struct ident *ident, enum namespace ns)
 {
 	if (!ident->keyword)
-- 
2.18.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux