Hi! As has been mentioned earlier, various parts of the COBOL FE and the library aren't endian clean. In the library that means that for now we have to live with no support for big endian targets, but in the FE that means that as well as not being able to build cross-compilers from big endian or pdp endian hosts to little endian targets which are otherwise supported.
The following patch attempts to fix one such spot, where it wants to encode in target byte ordering wide_int constants into 1, 2, 4, 8 or 16 bytes. We could wide_int_to_tree and then native_encode_expr, but so that we don't need to build the constants, the following patch exports from fold-const.cc a variant to native_encode_int which takes type and wide_int reference rather than an expression. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-04-02 Jakub Jelinek <ja...@redhat.com> PR cobol/119242 * fold-const.h (native_encode_wide_int): Declare. * fold-const.cc (native_encode_wide_int_1): New function template. (native_encode_wide_int): New function. (native_encode_int): Use native_encode_wide_int_1. * cobol/genapi.cc (binary_initial_from_float128): Use native_encode_wide_int. --- gcc/fold-const.h.jj 2025-03-28 10:38:23.165538304 +0100 +++ gcc/fold-const.h 2025-04-02 14:31:22.921136606 +0200 @@ -35,6 +35,8 @@ extern bool folding_cxx_constexpr; extern int native_encode_expr (const_tree, unsigned char *, int, int off = -1); extern int native_encode_initializer (tree, unsigned char *, int, int off = -1, unsigned char * = nullptr); +extern int native_encode_wide_int (tree, const wide_int_ref &, + unsigned char *, int, int off = -1); extern int native_encode_real (scalar_float_mode, const REAL_VALUE_TYPE *, unsigned char *, int, int off = -1); extern tree native_interpret_expr (tree, const unsigned char *, int); --- gcc/fold-const.cc.jj 2025-03-28 10:38:23.148538537 +0100 +++ gcc/fold-const.cc 2025-04-02 14:30:15.072074312 +0200 @@ -7465,15 +7465,17 @@ fold_plusminus_mult_expr (location_t loc return NULL_TREE; } -/* Subroutine of native_encode_expr. Encode the INTEGER_CST - specified by EXPR into the buffer PTR of length LEN bytes. + +/* Subroutine of native_encode_int and native_encode_wide_int. Encode the + integer VAL with type TYPE into the buffer PTR of length LEN bytes. Return the number of bytes placed in the buffer, or zero upon failure. */ +template <typename T> static int -native_encode_int (const_tree expr, unsigned char *ptr, int len, int off) +native_encode_wide_int_1 (tree type, const T &val, + unsigned char *ptr, int len, int off) { - tree type = TREE_TYPE (expr); int total_bytes; if (TREE_CODE (type) == BITINT_TYPE) { @@ -7516,7 +7518,7 @@ native_encode_int (const_tree expr, unsi int bitpos = byte * BITS_PER_UNIT; /* Extend EXPR according to TYPE_SIGN if the precision isn't a whole number of bytes. */ - value = wi::extract_uhwi (wi::to_widest (expr), bitpos, BITS_PER_UNIT); + value = wi::extract_uhwi (val, bitpos, BITS_PER_UNIT); if (total_bytes > UNITS_PER_WORD) { @@ -7537,6 +7539,31 @@ native_encode_int (const_tree expr, unsi return MIN (len, total_bytes - off); } +/* Encode the integer VAL with type TYPE into the buffer PTR of length LEN + bytes. + Return the number of bytes placed in the buffer, or zero + upon failure. */ + +int +native_encode_wide_int (tree type, const wide_int_ref &val, + unsigned char *ptr, int len, int off) +{ + return native_encode_wide_int_1 (type, val, ptr, len, off); +} + + +/* Subroutine of native_encode_expr. Encode the INTEGER_CST + specified by EXPR into the buffer PTR of length LEN bytes. + Return the number of bytes placed in the buffer, or zero + upon failure. */ + +static int +native_encode_int (const_tree expr, unsigned char *ptr, int len, int off) +{ + return native_encode_wide_int_1 (TREE_TYPE (expr), wi::to_widest (expr), + ptr, len, off); +} + /* Subroutine of native_encode_expr. Encode the FIXED_CST specified by EXPR into the buffer PTR of length LEN bytes. --- gcc/cobol/genapi.cc.jj 2025-04-02 10:36:25.517574640 +0200 +++ gcc/cobol/genapi.cc 2025-04-02 14:31:36.373950683 +0200 @@ -15216,25 +15216,19 @@ binary_initial_from_float128(cbl_field_t FIXED_WIDE_INT(128) i = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail, 128), SIGNED); - /* ??? Use native_encode_* below. */ retval = (char *)xmalloc(field->data.capacity); switch(field->data.capacity) { + tree type; case 1: - *(signed char *)retval = (signed char)i.slow (); - break; case 2: - *(signed short *)retval = (signed short)i.slow (); - break; case 4: - *(signed int *)retval = (signed int)i.slow (); - break; case 8: - *(signed long *)retval = (signed long)i.slow (); - break; case 16: - *(unsigned long *)retval = (unsigned long)i.ulow (); - *((signed long *)retval + 1) = (signed long)i.shigh (); + type = build_nonstandard_integer_type (field->data.capacity + * BITS_PER_UNIT, 0); + native_encode_wide_int (type, i, (unsigned char *)retval, + field->data.capacity); break; default: fprintf(stderr, Jakub