OSDN Git Service

2002-11-02 Toon Moene <toon@moene.indiv.nluug.nl>
[pf3gnuchains/gcc-fork.git] / gcc / f / target.c
index 638a71a..82ae955 100644 (file)
@@ -1,6 +1,6 @@
 /* target.c -- Implementation File (module.c template V1.0)
-   Copyright (C) 1995-1998 Free Software Foundation, Inc.
-   Contributed by James Craig Burley (burley@gnu.ai.mit.edu).
+   Copyright (C) 1995, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+   Contributed by James Craig Burley.
 
 This file is part of GNU Fortran.
 
@@ -69,13 +69,13 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 /* Include files. */
 
 #include "proj.h"
-#include <ctype.h>
-#include "glimits.j"
 #include "target.h"
+#include "diagnostic.h"
 #include "bad.h"
 #include "info.h"
 #include "lex.h"
 #include "malloc.h"
+#include "real.h"
 
 /* Externals defined here. */
 
@@ -131,7 +131,7 @@ ffetarget_print_char_ (FILE *f, unsigned char c)
       break;
 
     default:
-      if (isprint (c) && isascii (c))
+      if (ISPRINT (c))
        fputc (c, f);
       else
        fprintf (f, "\\%03o", (unsigned int) c);
@@ -215,17 +215,22 @@ ffetarget_align (ffetargetAlign *updated_alignment,
   ffetargetAlign i;
   ffetargetAlign j;
 
+  assert (alignment > 0);
+  assert (*updated_alignment > 0);
+  
   assert (*updated_modulo < *updated_alignment);
   assert (modulo < alignment);
 
-  /* The easy case: similar alignment requirements. */
-
+  /* The easy case: similar alignment requirements.  */
   if (*updated_alignment == alignment)
     {
       if (modulo > *updated_modulo)
        pad = alignment - (modulo - *updated_modulo);
       else
        pad = *updated_modulo - modulo;
+      if (offset < 0)
+       /* De-negatize offset, since % wouldn't do the expected thing.  */
+       offset = alignment - ((- offset) % alignment);
       pad = (offset + pad) % alignment;
       if (pad != 0)
        pad = alignment - pad;
@@ -241,7 +246,12 @@ ffetarget_align (ffetargetAlign *updated_alignment,
 
   cnt = ua / alignment;
 
-  min_pad = ~(ffetargetAlign) 0;/* Set to largest value. */
+  if (offset < 0)
+    /* De-negatize offset, since % wouldn't do the expected thing.  */
+    offset = ua - ((- offset) % ua);
+
+  /* Set to largest value.  */
+  min_pad = ~(ffetargetAlign) 0;
 
   /* Find all combinations of modulo values the two alignment requirements
      have; pick the combination that results in the smallest padding
@@ -252,21 +262,20 @@ ffetarget_align (ffetargetAlign *updated_alignment,
     {
       for (m = modulo, j = 0; j < cnt; m += alignment, ++j)
        {
-         if (m > um)           /* This code is similar to the "easy case"
-                                  code above. */
+         /* This code is similar to the "easy case" code above. */
+         if (m > um)
            pad = ua - (m - um);
          else
            pad = um - m;
          pad = (offset + pad) % ua;
-         if (pad != 0)
-           pad = ua - pad;
-         else
-           {                   /* A zero pad means we've got something
-                                  useful. */
+         if (pad == 0)
+           {
+             /* A zero pad means we've got something useful.  */
              *updated_alignment = ua;
              *updated_modulo = um;
              return 0;
            }
+         pad = ua - pad;
          if (pad < min_pad)
            {                   /* New minimum padding value. */
              min_pad = pad;
@@ -461,7 +470,7 @@ ffetarget_iszero_hollerith (ffetargetHollerith constant)
    data type info and the number of elements an array (1 for a scalar).         */
 
 void
-ffetarget_layout (char *error_text UNUSED, ffetargetAlign *alignment,
+ffetarget_layout (const char *error_text UNUSED, ffetargetAlign *alignment,
                  ffetargetAlign *modulo, ffetargetOffset *size,
                  ffeinfoBasictype bt, ffeinfoKindtype kt,
                  ffetargetCharacterSize charsize,
@@ -1439,12 +1448,8 @@ ffetarget_integerhex (ffetargetIntegerDefault *val, ffelexToken integer)
   bad_digit = FALSE;
   while (c != '\0')
     {
-      if ((c >= 'A') && (c <= 'F'))
-       c = c - 'A' + 10;
-      else if ((c >= 'a') && (c <= 'f'))
-       c = c - 'a' + 10;
-      else if ((c >= '0') && (c <= '9'))
-       c -= '0';
+      if (hex_p (c))
+       c = hex_value (c);
       else
        {
          bad_digit = TRUE;
@@ -2186,7 +2191,7 @@ ffetarget_print_hex (FILE *f, ffetargetTypeless value)
 {
   char *p;
   char digits[sizeof (value) * CHAR_BIT / 4 + 1];
-  static char hexdigits[16] = "0123456789ABCDEF";
+  static const char hexdigits[16] = "0123456789ABCDEF";
 
   if (f == NULL)
     f = dmpout;
@@ -2272,9 +2277,11 @@ ffetarget_real1 (ffetargetReal1 *value, ffelexToken integer,
 
   *p = '\0';
 
-  ffetarget_make_real1 (value,
-                       FFETARGET_ATOF_ (ptr,
-                                        SFmode));
+  {
+    REAL_VALUE_TYPE rv;
+    rv = FFETARGET_ATOF_ (ptr, SFmode);
+    ffetarget_make_real1 (value, rv);
+  }
 
   if (sz > ARRAY_SIZE (ffetarget_string_))
     malloc_kill_ks (malloc_pool_image (), ptr, sz);
@@ -2358,9 +2365,11 @@ ffetarget_real2 (ffetargetReal2 *value, ffelexToken integer,
 
   *p = '\0';
 
-  ffetarget_make_real2 (value,
-                       FFETARGET_ATOF_ (ptr,
-                                        DFmode));
+  {
+    REAL_VALUE_TYPE rv;
+    rv = FFETARGET_ATOF_ (ptr, DFmode);
+    ffetarget_make_real2 (value, rv);
+  }
 
   if (sz > ARRAY_SIZE (ffetarget_string_))
     malloc_kill_ks (malloc_pool_image (), ptr, sz);
@@ -2386,7 +2395,7 @@ ffetarget_typeless_binary (ffetargetTypeless *xvalue, ffelexToken token)
       new_value <<= 1;
       if ((new_value >> 1) != value)
        overflow = TRUE;
-      if (isdigit (c))
+      if (ISDIGIT (c))
        new_value += c - '0';
       else
        bad_digit = TRUE;
@@ -2430,7 +2439,7 @@ ffetarget_typeless_octal (ffetargetTypeless *xvalue, ffelexToken token)
       new_value <<= 3;
       if ((new_value >> 3) != value)
        overflow = TRUE;
-      if (isdigit (c))
+      if (ISDIGIT (c))
        new_value += c - '0';
       else
        bad_digit = TRUE;
@@ -2474,12 +2483,8 @@ ffetarget_typeless_hex (ffetargetTypeless *xvalue, ffelexToken token)
       new_value <<= 4;
       if ((new_value >> 4) != value)
        overflow = TRUE;
-      if (isdigit (c))
-       new_value += c - '0';
-      else if ((c >= 'A') && (c <= 'F'))
-       new_value += c - 'A' + 10;
-      else if ((c >= 'a') && (c <= 'f'))
-       new_value += c - 'a' + 10;
+      if (hex_p (c))
+       new_value += hex_value (c);
       else
        bad_digit = TRUE;
       value = new_value;
@@ -2519,6 +2524,33 @@ ffetarget_verify_character1 (mallocPool pool, ffetargetCharacter1 val)
 void *
 ffetarget_memcpy_ (void *dst, void *src, size_t len)
 {
+#ifdef CROSS_COMPILE
+  /* HOST_WORDS_BIG_ENDIAN corresponds to both WORDS_BIG_ENDIAN and
+     BYTES_BIG_ENDIAN (i.e. there are no HOST_ macros to represent a
+     difference in the two latter).  */
+  int host_words_big_endian =
+#ifndef HOST_WORDS_BIG_ENDIAN
+    0
+#else
+    HOST_WORDS_BIG_ENDIAN
+#endif
+    ;
+
+  /* This is just hands thrown up in the air over bits coming through this
+     function representing a number being memcpy:d as-is from host to
+     target.  We can't generally adjust endianness here since we don't
+     know whether it's an integer or floating point number; they're passed
+     differently.  Better to not emit code at all than to emit wrong code.
+     We will get some false hits because some data coming through here
+     seems to be just character vectors, but often enough it's numbers,
+     for instance in g77.f-torture/execute/980628-[4-6].f and alpha2.f.
+     Still, we compile *some* code.  FIXME: Rewrite handling of numbers.  */
+  if (!WORDS_BIG_ENDIAN != !host_words_big_endian
+      || !BYTES_BIG_ENDIAN != !host_words_big_endian)
+    sorry ("data initializer on host with different endianness");
+
+#endif /* CROSS_COMPILE */
+
   return (void *) memcpy (dst, src, len);
 }