summaryrefslogtreecommitdiff
path: root/src/common/asm.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-06-19 20:23:30 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-06-19 20:27:43 (GMT)
commit72b1c890ed19ebd7780e634d4874d12a619f259e (patch)
tree0d2e2f5e76ba9102a6671bdb2f7ab6b2e14c8d9c /src/common/asm.c
parentceeba88cafc4c7d2c625e53fb175b763e480f6ba (diff)
Extended the bitfield operations and their Python bindings.
Diffstat (limited to 'src/common/asm.c')
-rw-r--r--src/common/asm.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/common/asm.c b/src/common/asm.c
index 692256f..645bd6a 100644
--- a/src/common/asm.c
+++ b/src/common/asm.c
@@ -36,6 +36,34 @@ static const unsigned int _bval[16] = {
};
+/**
+ * Nombre de bits à 1 dans un octet.
+ *
+ * python3 -c "print(', '.join([ str(bin(n).count('1')) for n in range(256) ]))" | sed -re 's/(.{48})/\1\n/g' | sed 's/ $//'
+ */
+
+static const unsigned int _bcount[256] = {
+
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+
+};
+
+
/******************************************************************************
* *
@@ -111,3 +139,73 @@ bool msb_64(uint64_t v, unsigned int *p)
return true;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : v = valeur quelconque sur 32 bits. *
+* *
+* Description : Détermine le nombre de bits à 1 dans une valeur de 32 bits. *
+* *
+* Retour : Nombre de bits à 1. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+unsigned int popcount_32(uint32_t v)
+{
+ unsigned int result; /* Valeur à retourner */
+
+ /**
+ * Il existe de nombreuses méthodes pour obtenir le résultat attendu
+ * sans recourir à des extensions GCC ou à des instructions d'assembleur :
+ *
+ * - http://gurmeet.net/puzzles/fast-bit-counting-routines/
+ *
+ * On chosit un bon compromis entre efficacité et lecture.
+ *
+ */
+
+ result = _bcount[v & 0xff]
+ + _bcount[(v >> 8) & 0xff]
+ + _bcount[(v >> 16) & 0xff]
+ + _bcount[(v >> 24) & 0xff];
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : v = valeur quelconque sur 64 bits. *
+* *
+* Description : Détermine le nombre de bits à 1 dans une valeur de 64 bits. *
+* *
+* Retour : Nombre de bits à 1. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+unsigned int popcount_64(uint64_t v)
+{
+ unsigned int result; /* Valeur à retourner */
+
+ /**
+ * Cf. popcount_32().
+ */
+
+ result = _bcount[v & 0xff]
+ + _bcount[(v >> 8) & 0xff]
+ + _bcount[(v >> 16) & 0xff]
+ + _bcount[(v >> 24) & 0xff]
+ + _bcount[(v >> 32) & 0xff]
+ + _bcount[(v >> 40) & 0xff]
+ + _bcount[(v >> 48) & 0xff]
+ + _bcount[(v >> 56) & 0xff];
+
+ return result;
+
+}