Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
tests/tcg/alpha: Add test for cvttq
Test for invalid, integer overflow, and inexact. Test for proper result, modulo 2**64. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Acked-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20230527141910.1885950-3-richard.henderson@linaro.org>
- Loading branch information
Showing
2 changed files
with
79 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| #include <stdio.h> | ||
|
|
||
| #define FPCR_SUM (1UL << 63) | ||
| #define FPCR_INED (1UL << 62) | ||
| #define FPCR_UNFD (1UL << 61) | ||
| #define FPCR_UNDZ (1UL << 60) | ||
| #define FPCR_DYN_SHIFT 58 | ||
| #define FPCR_DYN_CHOPPED (0UL << FPCR_DYN_SHIFT) | ||
| #define FPCR_DYN_MINUS (1UL << FPCR_DYN_SHIFT) | ||
| #define FPCR_DYN_NORMAL (2UL << FPCR_DYN_SHIFT) | ||
| #define FPCR_DYN_PLUS (3UL << FPCR_DYN_SHIFT) | ||
| #define FPCR_DYN_MASK (3UL << FPCR_DYN_SHIFT) | ||
| #define FPCR_IOV (1UL << 57) | ||
| #define FPCR_INE (1UL << 56) | ||
| #define FPCR_UNF (1UL << 55) | ||
| #define FPCR_OVF (1UL << 54) | ||
| #define FPCR_DZE (1UL << 53) | ||
| #define FPCR_INV (1UL << 52) | ||
| #define FPCR_OVFD (1UL << 51) | ||
| #define FPCR_DZED (1UL << 50) | ||
| #define FPCR_INVD (1UL << 49) | ||
| #define FPCR_DNZ (1UL << 48) | ||
| #define FPCR_DNOD (1UL << 47) | ||
| #define FPCR_STATUS_MASK (FPCR_IOV | FPCR_INE | FPCR_UNF \ | ||
| | FPCR_OVF | FPCR_DZE | FPCR_INV) | ||
|
|
||
| static long test_cvttq(long *ret_e, double d) | ||
| { | ||
| unsigned long reset = (FPCR_INED | FPCR_UNFD | FPCR_OVFD | FPCR_DZED | | ||
| FPCR_INVD | FPCR_DYN_NORMAL); | ||
| long r, e; | ||
|
|
||
| asm("excb\n\t" | ||
| "mt_fpcr %3\n\t" | ||
| "excb\n\t" | ||
| "cvttq/svic %2, %0\n\t" | ||
| "excb\n\t" | ||
| "mf_fpcr %1\n\t" | ||
| "excb\n\t" | ||
| : "=f"(r), "=f"(e) | ||
| : "f"(d), "f"(reset)); | ||
|
|
||
| *ret_e = e & FPCR_STATUS_MASK; | ||
| return r; | ||
| } | ||
|
|
||
| int main (void) | ||
| { | ||
| static const struct { | ||
| double d; | ||
| long r; | ||
| long e; | ||
| } T[] = { | ||
| { 1.0, 1, 0 }, | ||
| { -1.0, -1, 0 }, | ||
| { 1.5, 1, FPCR_INE }, | ||
| { 0x1.0p32, 0x0000000100000000ul, 0 }, | ||
| { -0x1.0p63, 0x8000000000000000ul, 0 }, | ||
| { 0x1.0p63, 0x8000000000000000ul, FPCR_IOV | FPCR_INE }, | ||
| { 0x1.0p64, 0x0000000000000000ul, FPCR_IOV | FPCR_INE }, | ||
| { 0x1.cccp64, 0xccc0000000000000ul, FPCR_IOV | FPCR_INE }, | ||
| { __builtin_inf(), 0, FPCR_INV }, | ||
| { __builtin_nan(""), 0, FPCR_INV }, | ||
| }; | ||
|
|
||
| int i, err = 0; | ||
|
|
||
| for (i = 0; i < sizeof(T)/sizeof(T[0]); i++) { | ||
| long e, r = test_cvttq(&e, T[i].d); | ||
|
|
||
| if (r != T[i].r || e != T[i].e) { | ||
| printf("Fail %a: expect (%016lx : %04lx) got (%016lx : %04lx)\n", | ||
| T[i].d, T[i].r, T[i].e >> 48, r, e >> 48); | ||
| err = 1; | ||
| } | ||
| } | ||
| return err; | ||
| } |