+#define HIGH(T) (T)[1]
+#define LOW(T) (T)[0]
+#define U128(H, L) (vector unsigned long long) {L, H}
+#else
+#define HIGH(T) (T)[0]
+#define LOW(T) (T)[1]
+#define U128(H, L) (vector unsigned long long) {H, L}
+#endif
+
#define BCDSUB(vra, vrb, ps) \
asm ("bcdsub. %1,%2,%3,%4;" \
"mfocrf %0,0b10;" \
@@ -15,17 +26,18 @@
: "v" (vra), "v" (vrb), "i" (ps) \
: );
-#define TEST(vra, vrb, ps, exp_res, exp_cr6) \
- do { \
- __int128 vrt = 0; \
- int cr = 0; \
- BCDSUB(vra, vrb, ps); \
- if (exp_res) \
- assert(vrt == exp_res); \
- assert((cr >> 4) == exp_cr6); \
+#define TEST(vra, vrb, ps, exp_res_h, exp_res_l, exp_cr6) \
+ do { \
+ vector unsigned long long vrt = U128(0, 0); \
+ int cr = 0; \
+ BCDSUB(vra, vrb, ps); \
+ if (exp_res_h || exp_res_l) { \
+ assert(HIGH(vrt) == exp_res_h); \
+ assert(LOW(vrt) == exp_res_l); \
+ } \
+ assert((cr >> 4) == exp_cr6); \
} while (0)
-
/*
* Unbounded result is equal to zero:
* sign = (PS) ? 0b1111 : 0b1100
@@ -33,13 +45,13 @@
*/
void test_bcdsub_eq(void)
{
- __int128 a, b;
+ vector unsigned long long a, b;
/* maximum positive BCD value */
- a = b = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c);
+ a = b = U128(0x9999999999999999, 0x999999999999999c);
- TEST(a, b, 0, 0xc, CRF_EQ);
- TEST(a, b, 1, 0xf, CRF_EQ);
+ TEST(a, b, 0, 0x0, 0xc, CRF_EQ);
+ TEST(a, b, 1, 0x0, 0xf, CRF_EQ);
}
/*
@@ -49,21 +61,21 @@ void test_bcdsub_eq(void)
*/
void test_bcdsub_gt(void)
{
- __int128 a, b, c;
+ vector unsigned long long a, b, c;
/* maximum positive BCD value */
- a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999c);
+ a = U128(0x9999999999999999, 0x999999999999999c);
/* negative one BCD value */
- b = (__int128) 0x1d;
+ b = U128(0x0, 0x1d);
- TEST(a, b, 0, 0xc, (CRF_GT | CRF_SO));
- TEST(a, b, 1, 0xf, (CRF_GT | CRF_SO));
+ TEST(a, b, 0, 0x0, 0xc, (CRF_GT | CRF_SO));
+ TEST(a, b, 1, 0x0, 0xf, (CRF_GT | CRF_SO));
- c = (((__int128) 0x9999999999999999) << 64 | 0x999999999999998c);
+ c = U128(0x9999999999999999, 0x999999999999998c);
- TEST(c, b, 0, a, CRF_GT);
- TEST(c, b, 1, (a | 0x3), CRF_GT);
+ TEST(c, b, 0, HIGH(a), LOW(a), CRF_GT);
+ TEST(c, b, 1, HIGH(a), (LOW(a) | 0x3), CRF_GT);
}
/*
@@ -73,45 +85,45 @@ void test_bcdsub_gt(void)
*/
void test_bcdsub_lt(void)
{
- __int128 a, b;
+ vector unsigned long long a, b;
/* positive zero BCD value */
- a = (__int128) 0xc;
+ a = U128(0x0, 0xc);
/* positive one BCD value */
- b = (__int128) 0x1c;
+ b = U128(0x0, 0x1c);
- TEST(a, b, 0, 0x1d, CRF_LT);
- TEST(a, b, 1, 0x1d, CRF_LT);
+ TEST(a, b, 0, 0x0, 0x1d, CRF_LT);
+ TEST(a, b, 1, 0x0, 0x1d, CRF_LT);
/* maximum negative BCD value */
- a = (((__int128) 0x9999999999999999) << 64 | 0x999999999999999d);
+ a = U128(0x9999999999999999, 0x999999999999999d);
/* positive one BCD value */
- b = (__int128) 0x1c;
+ b = U128(0x0, 0x1c);
- TEST(a, b, 0, 0xd, (CRF_LT | CRF_SO));
- TEST(a, b, 1, 0xd, (CRF_LT | CRF_SO));
+ TEST(a, b, 0, 0x0, 0xd, (CRF_LT | CRF_SO));
+ TEST(a, b, 1, 0x0, 0xd, (CRF_LT | CRF_SO));
}
void test_bcdsub_invalid(void)
{
- __int128 a, b;
+ vector unsigned long long a, b;
/* positive one BCD value */
- a = (__int128) 0x1c;
- b = 0xf00;
+ a = U128(0x0, 0x1c);
+ b = U128(0x0, 0xf00);
- TEST(a, b, 0, UNDEF, CRF_SO);
- TEST(a, b, 1, UNDEF, CRF_SO);
+ TEST(a, b, 0, UNDEF, UNDEF, CRF_SO);
+ TEST(a, b, 1, UNDEF, UNDEF, CRF_SO);
- TEST(b, a, 0, UNDEF, CRF_SO);
- TEST(b, a, 1, UNDEF, CRF_SO);
+ TEST(b, a, 0, UNDEF, UNDEF, CRF_SO);
+ TEST(b, a, 1, UNDEF, UNDEF, CRF_SO);
- a = 0xbad;
+ a = U128(0x0, 0xbad);
- TEST(a, b, 0, UNDEF, CRF_SO);
- TEST(a, b, 1, UNDEF, CRF_SO);
+ TEST(a, b, 0, UNDEF, UNDEF, CRF_SO);
+ TEST(a, b, 1, UNDEF, UNDEF, CRF_SO);
}
int main(void)