]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fold-const, cobol: Add native_encode_wide_int and use it in COBOL FE [PR119242]
authorJakub Jelinek <jakub@redhat.com>
Thu, 3 Apr 2025 06:32:09 +0000 (08:32 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 3 Apr 2025 06:32:09 +0000 (08:32 +0200)
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 helper for native_encode_int which takes type and const wide_int_ref
reference rather than an expression.

2025-04-03  Jakub Jelinek  <jakub@redhat.com>

PR cobol/119242
gcc/
* fold-const.h (native_encode_wide_int): Declare.
* fold-const.cc (native_encode_wide_int): New function.
(native_encode_int): Use it.
gcc/cobol/
* genapi.cc (binary_initial_from_float128): Use
native_encode_wide_int.

gcc/cobol/genapi.cc
gcc/fold-const.cc
gcc/fold-const.h

index 4d958cfc0d4bfe052dbdbd59e6d085601bbcf27a..a0da6476e2a891ff259b847bfd3a896409ac369e 100644 (file)
@@ -15219,25 +15219,19 @@ binary_initial_from_float128(cbl_field_t *field, int rdigits,
   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,
index a4fb0147a0b1b74de0fff3b04a9a99e7a3d2084d..3e20538de9fd3c20466b4a14f43e916daacf5e71 100644 (file)
@@ -7465,15 +7465,16 @@ fold_plusminus_mult_expr (location_t loc, enum tree_code code, tree type,
   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.  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.  */
 
-static int
-native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
+int
+native_encode_wide_int (tree type, const wide_int_ref &val,
+                       unsigned char *ptr, int len, int off)
 {
-  tree type = TREE_TYPE (expr);
   int total_bytes;
   if (TREE_CODE (type) == BITINT_TYPE)
     {
@@ -7516,7 +7517,7 @@ native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
       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 +7538,18 @@ native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
   return MIN (len, total_bytes - 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 (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.
index 43deea4d69c5d97e6d5c3735efb733e0974bff7c..e95cf48c17665fa3136a902c36de9586140293a5 100644 (file)
@@ -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);