Jakub Jelinek <ja...@redhat.com> writes:
> 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);
>  }

I'm not sure the _1 template is worth it.  wi::to_widest ->
const wide_int_ref & should be very cheap (it doesn't for example
construct a widest_int), so I think native_encode_int could call
native_encode_wide_int.

LGTM otherwise.

Thanks,
Richard

>  
> +/* 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

Reply via email to