aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Leoshkevich <iii@linux.ibm.com>2023-05-11 13:46:50 +0200
committerThomas Huth <thuth@redhat.com>2023-05-16 09:14:18 +0200
commitf8d7c90f836370d2a0c8fee8e6c43d49d35ad770 (patch)
tree5cba8cd5bc27e47f8c7c592088df2e247ac57fa1
parent970641de01908dd09b569965e78f13842e5854bc (diff)
downloadqemu-f8d7c90f836370d2a0c8fee8e6c43d49d35ad770.zip
qemu-f8d7c90f836370d2a0c8fee8e6c43d49d35ad770.tar.gz
qemu-f8d7c90f836370d2a0c8fee8e6c43d49d35ad770.tar.bz2
tests/tcg/multiarch: Make the system memory test work on big-endian
Store the bytes in descending order on big-endian. Invert the logic in the multi-byte signed tests on big-endian. Make the checks in the multi-byte signed tests stricter. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20230511114651.439872-2-iii@linux.ibm.com> Signed-off-by: Thomas Huth <thuth@redhat.com>
-rw-r--r--tests/tcg/multiarch/system/memory.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/tests/tcg/multiarch/system/memory.c b/tests/tcg/multiarch/system/memory.c
index 214f7d4..e29786a 100644
--- a/tests/tcg/multiarch/system/memory.c
+++ b/tests/tcg/multiarch/system/memory.c
@@ -40,18 +40,21 @@ static void pdot(int count)
}
/*
- * Helper macros for shift/extract so we can keep our endian handling
- * in one place.
+ * Helper macros for endian handling.
*/
-#define BYTE_SHIFT(b, pos) ((uint64_t)b << (pos * 8))
-#define BYTE_EXTRACT(b, pos) ((b >> (pos * 8)) & 0xff)
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define BYTE_SHIFT(b, pos) (b << (pos * 8))
+#define BYTE_NEXT(b) ((b)++)
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define BYTE_SHIFT(b, pos) (b << ((sizeof(b) - 1 - (pos)) * 8))
+#define BYTE_NEXT(b) (--(b))
+#else
+#error Unsupported __BYTE_ORDER__
+#endif
/*
- * Fill the data with ascending value bytes.
- *
- * Currently we only support Little Endian machines so write in
- * ascending address order. When we read higher address bytes should
- * either be zero or higher than the lower bytes.
+ * Fill the data with ascending (for little-endian) or descending (for
+ * big-endian) value bytes.
*/
static void init_test_data_u8(int unused_offset)
@@ -62,14 +65,14 @@ static void init_test_data_u8(int unused_offset)
ml_printf("Filling test area with u8:");
for (i = 0; i < TEST_SIZE; i++) {
- *ptr++ = count++;
+ *ptr++ = BYTE_NEXT(count);
pdot(i);
}
ml_printf("done\n");
}
/*
- * Full the data with alternating positive and negative bytes. This
+ * Fill the data with alternating positive and negative bytes. This
* should mean for reads larger than a byte all subsequent reads will
* stay either negative or positive. We never write 0.
*/
@@ -119,7 +122,7 @@ static void init_test_data_u16(int offset)
reset_start_data(offset);
for (i = 0; i < max; i++) {
- uint8_t low = count++, high = count++;
+ uint16_t low = BYTE_NEXT(count), high = BYTE_NEXT(count);
word = BYTE_SHIFT(high, 1) | BYTE_SHIFT(low, 0);
*ptr++ = word;
pdot(i);
@@ -139,9 +142,10 @@ static void init_test_data_u32(int offset)
reset_start_data(offset);
for (i = 0; i < max; i++) {
- uint8_t b4 = count++, b3 = count++;
- uint8_t b2 = count++, b1 = count++;
- word = BYTE_SHIFT(b1, 3) | BYTE_SHIFT(b2, 2) | BYTE_SHIFT(b3, 1) | b4;
+ uint32_t b4 = BYTE_NEXT(count), b3 = BYTE_NEXT(count);
+ uint32_t b2 = BYTE_NEXT(count), b1 = BYTE_NEXT(count);
+ word = BYTE_SHIFT(b1, 3) | BYTE_SHIFT(b2, 2) | BYTE_SHIFT(b3, 1) |
+ BYTE_SHIFT(b4, 0);
*ptr++ = word;
pdot(i);
}
@@ -160,13 +164,13 @@ static void init_test_data_u64(int offset)
reset_start_data(offset);
for (i = 0; i < max; i++) {
- uint8_t b8 = count++, b7 = count++;
- uint8_t b6 = count++, b5 = count++;
- uint8_t b4 = count++, b3 = count++;
- uint8_t b2 = count++, b1 = count++;
+ uint64_t b8 = BYTE_NEXT(count), b7 = BYTE_NEXT(count);
+ uint64_t b6 = BYTE_NEXT(count), b5 = BYTE_NEXT(count);
+ uint64_t b4 = BYTE_NEXT(count), b3 = BYTE_NEXT(count);
+ uint64_t b2 = BYTE_NEXT(count), b1 = BYTE_NEXT(count);
word = BYTE_SHIFT(b1, 7) | BYTE_SHIFT(b2, 6) | BYTE_SHIFT(b3, 5) |
BYTE_SHIFT(b4, 4) | BYTE_SHIFT(b5, 3) | BYTE_SHIFT(b6, 2) |
- BYTE_SHIFT(b7, 1) | b8;
+ BYTE_SHIFT(b7, 1) | BYTE_SHIFT(b8, 0);
*ptr++ = word;
pdot(i);
}
@@ -374,12 +378,20 @@ static bool read_test_data_s16(int offset, bool neg_first)
ml_printf("Reading s16 from %#lx (offset %d, %s):", ptr,
offset, neg_first ? "neg" : "pos");
+ /*
+ * If the first byte is negative, then the last byte is positive.
+ * Therefore the logic below must be flipped for big-endian.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ neg_first = !neg_first;
+#endif
+
for (i = 0; i < max; i++) {
int32_t data = *ptr++;
if (neg_first && data < 0) {
pdot(i);
- } else if (data > 0) {
+ } else if (!neg_first && data > 0) {
pdot(i);
} else {
ml_printf("Error %d %c 0\n", data, neg_first ? '<' : '>');
@@ -399,12 +411,20 @@ static bool read_test_data_s32(int offset, bool neg_first)
ml_printf("Reading s32 from %#lx (offset %d, %s):",
ptr, offset, neg_first ? "neg" : "pos");
+ /*
+ * If the first byte is negative, then the last byte is positive.
+ * Therefore the logic below must be flipped for big-endian.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ neg_first = !neg_first;
+#endif
+
for (i = 0; i < max; i++) {
int64_t data = *ptr++;
if (neg_first && data < 0) {
pdot(i);
- } else if (data > 0) {
+ } else if (!neg_first && data > 0) {
pdot(i);
} else {
ml_printf("Error %d %c 0\n", data, neg_first ? '<' : '>');
@@ -419,8 +439,7 @@ static bool read_test_data_s32(int offset, bool neg_first)
* Read the test data and verify at various offsets
*
* For everything except bytes all our reads should be either positive
- * or negative depending on what offset we are reading from. Currently
- * we only handle LE systems.
+ * or negative depending on what offset we are reading from.
*/
read_sfn read_sfns[] = { read_test_data_s8,
read_test_data_s16,