5 #define CRF_LT (1 << 3)
6 #define CRF_GT (1 << 2)
7 #define CRF_EQ (1 << 1)
8 #define CRF_SO (1 << 0)
11 #define BCDSUB(vra, vrb, ps) \
12 asm ("bcdsub. %1,%2,%3,%4;" \
14 : "=r" (cr), "=v" (vrt) \
15 : "v" (vra), "v" (vrb), "i" (ps) \
18 #define TEST(vra, vrb, ps, exp_res, exp_cr6) \
22 BCDSUB(vra, vrb, ps); \
24 assert(vrt == exp_res); \
25 assert((cr >> 4) == exp_cr6); \
30 * Unbounded result is equal to zero:
31 * sign = (PS) ? 0b1111 : 0b1100
34 void test_bcdsub_eq(void)
38 /* maximum positive BCD value */
39 a
= b
= (((__int128
) 0x9999999999999999) << 64 | 0x999999999999999c);
41 TEST(a
, b
, 0, 0xc, CRF_EQ
);
42 TEST(a
, b
, 1, 0xf, CRF_EQ
);
46 * Unbounded result is greater than zero:
47 * sign = (PS) ? 0b1111 : 0b1100
48 * CR6 = (overflow) ? 0b0101 : 0b0100
50 void test_bcdsub_gt(void)
54 /* maximum positive BCD value */
55 a
= (((__int128
) 0x9999999999999999) << 64 | 0x999999999999999c);
57 /* negative one BCD value */
60 TEST(a
, b
, 0, 0xc, (CRF_GT
| CRF_SO
));
61 TEST(a
, b
, 1, 0xf, (CRF_GT
| CRF_SO
));
63 c
= (((__int128
) 0x9999999999999999) << 64 | 0x999999999999998c);
65 TEST(c
, b
, 0, a
, CRF_GT
);
66 TEST(c
, b
, 1, (a
| 0x3), CRF_GT
);
70 * Unbounded result is less than zero:
72 * CR6 = (overflow) ? 0b1001 : 0b1000
74 void test_bcdsub_lt(void)
78 /* positive zero BCD value */
81 /* positive one BCD value */
84 TEST(a
, b
, 0, 0x1d, CRF_LT
);
85 TEST(a
, b
, 1, 0x1d, CRF_LT
);
87 /* maximum negative BCD value */
88 a
= (((__int128
) 0x9999999999999999) << 64 | 0x999999999999999d);
90 /* positive one BCD value */
93 TEST(a
, b
, 0, 0xd, (CRF_LT
| CRF_SO
));
94 TEST(a
, b
, 1, 0xd, (CRF_LT
| CRF_SO
));
97 void test_bcdsub_invalid(void)
101 /* positive one BCD value */
105 TEST(a
, b
, 0, UNDEF
, CRF_SO
);
106 TEST(a
, b
, 1, UNDEF
, CRF_SO
);
108 TEST(b
, a
, 0, UNDEF
, CRF_SO
);
109 TEST(b
, a
, 1, UNDEF
, CRF_SO
);
113 TEST(a
, b
, 0, UNDEF
, CRF_SO
);
114 TEST(a
, b
, 1, UNDEF
, CRF_SO
);
119 struct sigaction action
;
121 action
.sa_handler
= _exit
;
122 sigaction(SIGABRT
, &action
, NULL
);
127 test_bcdsub_invalid();