diff options
author | David Faust <david.faust@oracle.com> | 2023-01-10 10:53:12 -0800 |
---|---|---|
committer | David Faust <david.faust@oracle.com> | 2023-01-11 08:36:48 -0800 |
commit | c7279270a2deda81eaeba37a87d721bee0ed6004 (patch) | |
tree | 238d9aaa375eb8c178d3331cc06469d8a13eaae5 /gcc/config/bpf | |
parent | 3e1cba12a8d71e70235a9a9b8f1a237a561db3e7 (diff) | |
download | gcc-c7279270a2deda81eaeba37a87d721bee0ed6004.zip gcc-c7279270a2deda81eaeba37a87d721bee0ed6004.tar.gz gcc-c7279270a2deda81eaeba37a87d721bee0ed6004.tar.bz2 |
bpf: correct bpf_print_operand for floats [PR108293]
The existing logic in bpf_print_operand was only correct for integral
CONST_DOUBLEs, and emitted garbage for floating point modes. Fix it so
floating point mode operands are correctly handled.
PR target/108293
gcc/
* config/bpf/bpf.cc (bpf_print_operand): Correct handling for
floating point modes.
gcc/testsuite/
* gcc.target/bpf/double-1.c: New test.
* gcc.target/bpf/double-2.c: New test.
* gcc.target/bpf/float-1.c: New test.
Diffstat (limited to 'gcc/config/bpf')
-rw-r--r-- | gcc/config/bpf/bpf.cc | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc index 2aeaeaf..576a1fe8 100644 --- a/gcc/config/bpf/bpf.cc +++ b/gcc/config/bpf/bpf.cc @@ -880,13 +880,35 @@ bpf_print_operand (FILE *file, rtx op, int code ATTRIBUTE_UNUSED) output_address (GET_MODE (op), XEXP (op, 0)); break; case CONST_DOUBLE: - if (CONST_DOUBLE_HIGH (op)) - fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, - CONST_DOUBLE_HIGH (op), CONST_DOUBLE_LOW (op)); - else if (CONST_DOUBLE_LOW (op) < 0) - fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op)); + if (GET_MODE (op) == VOIDmode) + { + if (CONST_DOUBLE_HIGH (op)) + fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, + CONST_DOUBLE_HIGH (op), CONST_DOUBLE_LOW (op)); + else if (CONST_DOUBLE_LOW (op) < 0) + fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (op)); + else + fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (op)); + } else - fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (op)); + { + long vals[2]; + real_to_target (vals, CONST_DOUBLE_REAL_VALUE (op), GET_MODE (op)); + vals[0] &= 0xffffffff; + vals[1] &= 0xffffffff; + if (GET_MODE (op) == SFmode) + fprintf (file, "0x%08lx", vals[0]); + else if (GET_MODE (op) == DFmode) + { + /* Note: real_to_target puts vals in target word order. */ + if (WORDS_BIG_ENDIAN) + fprintf (file, "0x%08lx%08lx", vals[0], vals[1]); + else + fprintf (file, "0x%08lx%08lx", vals[1], vals[0]); + } + else + gcc_unreachable (); + } break; default: output_addr_const (file, op); |