bitXXgen: add osmo_loadXXbe_ext_2() to get right-adjusted values

As shown in the recently added bitgen_test.c, using osmo_loadXXbe_ext() with a
smaller n produces results aligned on the most significant bytes, which is
cumbersome, since it does not return a previously stored value. This problem
exists only for the big-endian functions, the little-endian osmo_loadXXle_ext()
properly return values adjusted on the least significant octets.

Add osmo_loadXXbe_ext_2() variants that properly right-adjust the returned
value. Prominently highlight this behavior in API doc. Test the new functions
in bitgen_test.c.

For example, this eases handling of 24bit integers (e.g. loaded from buffer to
uint32_t, and stored into buffer from uint32_t). Also explicitly show this 24
bit case in bitgen_test.c

Change-Id: I2806df6f0f7bf1ad705d52fa386d4525b892b928
diff --git a/tests/bitgen/bitgen_test.c b/tests/bitgen/bitgen_test.c
index 0c9821e..8657bbe 100644
--- a/tests/bitgen/bitgen_test.c
+++ b/tests/bitgen/bitgen_test.c
@@ -22,10 +22,25 @@
 				read_val = osmo_load##SIZE####BE_LE##_ext(&buf[at_idx], len); \
 				printf("osmo_load" #SIZE #BE_LE "_ext(&buf[%d], %d) = 0x%" PRIx##SIZE "\n", \
 				       at_idx, len, read_val); \
+				\
+				if (!strcmp(#BE_LE, "be")) { \
+					read_val = osmo_load##SIZE####BE_LE##_ext_2(&buf[at_idx], len); \
+					printf("osmo_load" #SIZE #BE_LE "_ext_2(&buf[%d], %d) = 0x%" PRIx##SIZE "\n", \
+					       at_idx, len, read_val); \
+				} \
 			} \
 		} \
 	} while (0)
 
+/* Shims to allow compiling, the *le_ext_2 are not actually invoked because of the strcmp() condition above. */
+#define osmo_load16le_ext_2 dummy
+#define osmo_load32le_ext_2 dummy
+#define osmo_load64le_ext_2 dummy
+
+static inline uint64_t dummy(const void *p, uint8_t n)
+{
+	OSMO_ASSERT(false);
+}
 
 int main(int argc, char **argv)
 {
@@ -37,7 +52,7 @@
 	DO_TEST(le, 64);
 
 	{
-		printf("--- store/load 0x112233 as 24bit big-endian\n");
+		printf("--- store/load 0x112233 as 24bit big-endian, legacy\n");
 		uint8_t buf[4];
 		memset(buf, 0, sizeof(buf));
 		osmo_store32be_ext(0x00112233, buf, 3); // stores 11 22 33
@@ -47,6 +62,16 @@
 	}
 
 	{
+		printf("--- store/load 0x112233 as 24bit big-endian\n");
+		uint8_t buf[4];
+		memset(buf, 0, sizeof(buf));
+		osmo_store32be_ext(0x00112233, buf, 3); // stores 11 22 33
+		printf("%s\n", osmo_hexdump(buf, 4));
+		uint32_t r = osmo_load32be_ext_2(buf, 3); // returns 0x00112233
+		printf("0x%x\n", r);
+	}
+
+	{
 		printf("--- store/load 0x112233 as 24bit little-endian\n");
 		uint8_t buf[4];
 		memset(buf, 0, sizeof(buf));