Add big endian support for s390x architecture.
Signed-off-by: Vivian Kong <vivkong@ca.ibm.com>
---
app/test/test_cmdline_ipaddr.c | 13 +++-
app/test/test_cmdline_num.c | 111 +++++++++++++++++++++++++++++++++
app/test/test_xmmt_ops.h | 14 +++++
3 files changed, 137 insertions(+), 1 deletion(-)
@@ -6,6 +6,7 @@
#include <string.h>
#include <inttypes.h>
#include <netinet/in.h>
+#include <rte_byteorder.h>
#ifndef __linux__
#ifndef __FreeBSD__
@@ -22,7 +23,8 @@
#include "test_cmdline.h"
-#define IP4(a,b,c,d) {((uint32_t)(((a) & 0xff)) | \
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define IP4(a, b, c, d) {((uint32_t)(((a) & 0xff)) | \
(((b) & 0xff) << 8) | \
(((c) & 0xff) << 16) | \
((d) & 0xff) << 24)}
@@ -30,6 +32,15 @@
#define U16_SWAP(x) \
(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8))
+#else
+#define IP4(a, b, c, d) {((uint32_t)(((a) & 0xff) << 24) | \
+ (((b) & 0xff) << 16) | \
+ (((c) & 0xff) << 8) | \
+ ((d) & 0xff))}
+
+#define U16_SWAP(x) x
+#endif
+
/* create IPv6 address, swapping bytes where needed */
#ifndef s6_addr16
# define s6_addr16 __u6_addr.__u6_addr16
@@ -11,6 +11,8 @@
#include <cmdline_parse.h>
#include <cmdline_parse_num.h>
+
+#include <rte_byteorder.h>
#include "test_cmdline.h"
struct num_unsigned_str {
@@ -451,6 +453,48 @@ test_parse_num_valid(void)
/* check if result matches what it should have matched
* since unsigned numbers don't care about number of bits, we can just convert
* everything to uint64_t without any worries. */
+ #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+ switch (type) {
+ case UINT8:
+ {
+ uint8_t *temp = (uint8_t *)&result;
+ result = *temp;
+ break;
+ }
+ case UINT16:
+ {
+ uint16_t *temp = (uint16_t *)&result;
+ result = *temp;
+ break;
+ }
+ case UINT32:
+ {
+ uint32_t *temp = (uint32_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT8:
+ {
+ int8_t *temp = (int8_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT16:
+ {
+ int16_t *temp = (int16_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT32:
+ {
+ int32_t *temp = (int32_t *)&result;
+ result = *temp;
+ break;
+ }
+ default:
+ break;
+ }
+ #endif
if (ret > 0 && num_valid_positive_strs[i].result != result) {
printf("Error: parsing %s as %s failed: result mismatch!\n",
num_valid_positive_strs[i].str, buf);
@@ -480,6 +524,7 @@ test_parse_num_valid(void)
* the result is signed in this case, so we have to account for that */
if (ret > 0) {
/* detect negative */
+ #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
switch (type) {
case INT8:
result = (int8_t) result;
@@ -493,6 +538,30 @@ test_parse_num_valid(void)
default:
break;
}
+ #else
+ switch (type) {
+ case INT8:
+ {
+ int8_t *temp = (int8_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT16:
+ {
+ int16_t *temp = (int16_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT32:
+ {
+ int32_t *temp = (int32_t *)&result;
+ result = *temp;
+ break;
+ }
+ default:
+ break;
+ }
+ #endif
if (num_valid_negative_strs[i].result == (int64_t) result)
continue;
printf("Error: parsing %s as %s failed: result mismatch!\n",
@@ -529,6 +598,48 @@ test_parse_num_valid(void)
/* check if result matches what it should have matched
* since unsigned numbers don't care about number of bits, we can just convert
* everything to uint64_t without any worries. */
+ #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
+ switch (type) {
+ case UINT8:
+ {
+ uint8_t *temp = (uint8_t *)&result;
+ result = *temp;
+ break;
+ }
+ case UINT16:
+ {
+ uint16_t *temp = (uint16_t *)&result;
+ result = *temp;
+ break;
+ }
+ case UINT32:
+ {
+ uint32_t *temp = (uint32_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT8:
+ {
+ int8_t *temp = (int8_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT16:
+ {
+ int16_t *temp = (int16_t *)&result;
+ result = *temp;
+ break;
+ }
+ case INT32:
+ {
+ int32_t *temp = (int32_t *)&result;
+ result = *temp;
+ break;
+ }
+ default:
+ break;
+ }
+ #endif
if (ret > 0 && num_garbage_positive_strs[i].result != result) {
printf("Error: parsing %s as %s failed: result mismatch!\n",
num_garbage_positive_strs[i].str, buf);
@@ -49,6 +49,20 @@ vect_set_epi32(int i3, int i2, int i1, int i0)
return data;
}
+#elif defined(RTE_ARCH_S390X)
+
+/* loads the xmm_t value from address p(does not need to be 16-byte aligned)*/
+#define vect_loadu_sil128(p) vec_xld2(0, (signed int *)p)
+
+/* sets the 4 signed 32-bit integer values and returns the xmm_t variable */
+static __rte_always_inline xmm_t
+vect_set_epi32(int i3, int i2, int i1, int i0)
+{
+ xmm_t data = (xmm_t){i0, i1, i2, i3};
+
+ return data;
+}
+
#endif
#endif /* _TEST_XMMT_OPS_H_ */