⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 target.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* target.c -- Implementation File (module.c template V1.0)   Copyright (C) 1995-1998 Free Software Foundation, Inc.   Contributed by James Craig Burley.This file is part of GNU Fortran.GNU Fortran is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Fortran is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Fortran; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.   Related Modules:      None   Description:      Implements conversion of lexer tokens to machine-dependent numerical      form and accordingly issues diagnostic messages when necessary.      Also, this module, especially its .h file, provides nearly all of the      information on the target machine's data type, kind type, and length      type capabilities.  The idea is that by carefully going through      target.h and changing things properly, one can accomplish much      towards the porting of the FFE to a new machine.	There are limits      to how much this can accomplish towards that end, however.  For one      thing, the ffeexpr_collapse_convert function doesn't contain all the      conversion cases necessary, because the text file would be      enormous (even though most of the function would be cut during the      cpp phase because of the absence of the types), so when adding to      the number of supported kind types for a given type, one must look      to see if ffeexpr_collapse_convert needs modification in this area,      in addition to providing the appropriate macros and functions in      ffetarget.  Note that if combinatorial explosion actually becomes a      problem for a given machine, one might have to modify the way conversion      expressions are built so that instead of just one conversion expr, a      series of conversion exprs are built to make a path from one type to      another that is not a "near neighbor".  For now, however, with a handful      of each of the numeric types and only one character type, things appear      manageable.      A nonobvious change to ffetarget would be if the target machine was      not a 2's-complement machine.  Any item with the word "magical" (case-      insensitive) in the FFE's source code (at least) indicates an assumption      that a 2's-complement machine is the target, and thus that there exists      a magnitude that can be represented as a negative number but not as      a positive number.  It is possible that this situation can be dealt      with by changing only ffetarget, for example, on a 1's-complement      machine, perhaps #defineing ffetarget_constant_is_magical to simply      FALSE along with making the appropriate changes in ffetarget's number      parsing functions would be sufficient to effectively "comment out" code      in places like ffeexpr that do certain magical checks.  But it is      possible there are other 2's-complement dependencies lurking in the      FFE (as possibly is true of any large program); if you find any, please      report them so we can replace them with dependencies on ffetarget      instead.   Modifications:*//* Include files. */#include "proj.h"#include "glimits.j"#include "target.h"#include "bad.h"#include "info.h"#include "lex.h"#include "malloc.h"/* Externals defined here. */char ffetarget_string_[40];	/* Temp for ascii-to-double (atof). */HOST_WIDE_INT ffetarget_long_val_;HOST_WIDE_INT ffetarget_long_junk_;/* Simple definitions and enumerations. *//* Internal typedefs. *//* Private include files. *//* Internal structure definitions. *//* Static objects accessed by functions in this module. *//* Static functions (internal). */static void ffetarget_print_char_ (FILE *f, unsigned char c);/* Internal macros. */#ifdef REAL_VALUE_ATOF#define FFETARGET_ATOF_(p,m) REAL_VALUE_ATOF ((p),(m))#else#define FFETARGET_ATOF_(p,m) atof ((p))#endif/* ffetarget_print_char_ -- Print a single character (in apostrophe context)   See prototype.   Outputs char so it prints or is escaped C style.  */static voidffetarget_print_char_ (FILE *f, unsigned char c){  switch (c)    {    case '\\':      fputs ("\\\\", f);      break;    case '\'':      fputs ("\\\'", f);      break;    default:      if (ISPRINT (c))	fputc (c, f);      else	fprintf (f, "\\%03o", (unsigned int) c);      break;    }}/* ffetarget_aggregate_info -- Determine type for aggregate storage area   See prototype.   If aggregate type is distinct, just return it.  Else return a type   representing a common denominator for the nondistinct type (for now,   just return default character, since that'll work on almost all target   machines).   The rules for abt/akt are (as implemented by ffestorag_update):   abt == FFEINFO_basictypeANY (akt == FFEINFO_kindtypeANY also, by   definition): CHARACTER and non-CHARACTER types mixed.   abt == FFEINFO_basictypeNONE (akt == FFEINFO_kindtypeNONE also, by   definition): More than one non-CHARACTER type mixed, but no CHARACTER   types mixed in.   abt some other value, akt == FFEINFO_kindtypeNONE: abt indicates the   only basic type mixed in, but more than one kind type is mixed in.   abt some other value, akt some other value: abt and akt indicate the   only type represented in the aggregation.  */voidffetarget_aggregate_info (ffeinfoBasictype *ebt, ffeinfoKindtype *ekt,			  ffetargetAlign *units, ffeinfoBasictype abt,			  ffeinfoKindtype akt){  ffetype type;  if ((abt == FFEINFO_basictypeNONE) || (abt == FFEINFO_basictypeANY)      || (akt == FFEINFO_kindtypeNONE))    {      *ebt = FFEINFO_basictypeCHARACTER;      *ekt = FFEINFO_kindtypeCHARACTERDEFAULT;    }  else    {      *ebt = abt;      *ekt = akt;    }  type = ffeinfo_type (*ebt, *ekt);  assert (type != NULL);  *units = ffetype_size (type);}/* ffetarget_align -- Align one storage area to superordinate, update super   See prototype.   updated_alignment/updated_modulo contain the already existing   alignment requirements for the storage area at whose offset the   object with alignment requirements alignment/modulo is to be placed.   Find the smallest pad such that the requirements are maintained and   return it, but only after updating the updated_alignment/_modulo   requirements as necessary to indicate the placement of the new object.  */ffetargetAlignffetarget_align (ffetargetAlign *updated_alignment,		 ffetargetAlign *updated_modulo, ffetargetOffset offset,		 ffetargetAlign alignment, ffetargetAlign modulo){  ffetargetAlign pad;  ffetargetAlign min_pad;	/* Minimum amount of padding needed. */  ffetargetAlign min_m = 0;	/* Minimum-padding m. */  ffetargetAlign ua;		/* Updated alignment. */  ffetargetAlign um;		/* Updated modulo. */  ffetargetAlign ucnt;		/* Multiplier applied to ua. */  ffetargetAlign m;		/* Copy of modulo. */  ffetargetAlign cnt;		/* Multiplier applied to 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.  */  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;      return pad;    }  /* Sigh, find LCM (Least Common Multiple) for the two alignment factors. */  for (ua = *updated_alignment, ucnt = 1;       ua % alignment != 0;       ua += *updated_alignment)    ++ucnt;  cnt = ua / alignment;  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     requirement.  Of course, if a zero-pad requirement is encountered, just     use that one. */  for (um = *updated_modulo, i = 0; i < ucnt; um += *updated_alignment, ++i)    {      for (m = modulo, j = 0; j < cnt; m += alignment, ++j)	{	  /* 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)	    {	      /* 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;	      min_m = um;	    }	}    }  *updated_alignment = ua;  *updated_modulo = min_m;  return min_pad;}/* Always append a null byte to the end, in case this is wanted in   a special case such as passing a string as a FORMAT or %REF.   Done to save a bit of hassle, nothing more, but it's a kludge anyway,   because it isn't a "feature" that is self-documenting.  Use the   string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature   in the code.  */#if FFETARGET_okCHARACTER1boolffetarget_character1 (ffetargetCharacter1 *val, ffelexToken character,		      mallocPool pool){  val->length = ffelex_token_length (character);  if (val->length == 0)    val->text = NULL;  else    {      val->text = malloc_new_kp (pool, "ffetargetCharacter1", val->length + 1);      memcpy (val->text, ffelex_token_text (character), val->length);      val->text[val->length] = '\0';    }  return TRUE;}#endif/* Produce orderable comparison between two constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1intffetarget_cmp_character1 (ffetargetCharacter1 l, ffetargetCharacter1 r){  if (l.length < r.length)    return -1;  if (l.length > r.length)    return 1;  if (l.length == 0)    return 0;  return memcmp (l.text, r.text, l.length);}#endif/* ffetarget_concatenate_character1 -- Perform CONCAT op on two constants   Always append a null byte to the end, in case this is wanted in   a special case such as passing a string as a FORMAT or %REF.   Done to save a bit of hassle, nothing more, but it's a kludge anyway,   because it isn't a "feature" that is self-documenting.  Use the   string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature   in the code.  */#if FFETARGET_okCHARACTER1ffebadffetarget_concatenate_character1 (ffetargetCharacter1 *res,	      ffetargetCharacter1 l, ffetargetCharacter1 r, mallocPool pool,				  ffetargetCharacterSize *len){  res->length = *len = l.length + r.length;  if (*len == 0)    res->text = NULL;  else    {      res->text = malloc_new_kp (pool, "ffetargetCharacter1(CONCAT)", *len + 1);      if (l.length != 0)	memcpy (res->text, l.text, l.length);      if (r.length != 0)	memcpy (res->text + l.length, r.text, r.length);      res->text[*len] = '\0';    }  return FFEBAD;}#endif/* ffetarget_eq_character1 -- Perform relational comparison on char constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1ffebadffetarget_eq_character1 (bool *res, ffetargetCharacter1 l,			 ffetargetCharacter1 r){  assert (l.length == r.length);  *res = (memcmp (l.text, r.text, l.length) == 0);  return FFEBAD;}#endif/* ffetarget_le_character1 -- Perform relational comparison on char constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1ffebadffetarget_le_character1 (bool *res, ffetargetCharacter1 l,			 ffetargetCharacter1 r){  assert (l.length == r.length);  *res = (memcmp (l.text, r.text, l.length) <= 0);  return FFEBAD;}#endif/* ffetarget_lt_character1 -- Perform relational comparison on char constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1ffebadffetarget_lt_character1 (bool *res, ffetargetCharacter1 l,			 ffetargetCharacter1 r){  assert (l.length == r.length);  *res = (memcmp (l.text, r.text, l.length) < 0);  return FFEBAD;}#endif/* ffetarget_ge_character1 -- Perform relational comparison on char constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1ffebadffetarget_ge_character1 (bool *res, ffetargetCharacter1 l,			 ffetargetCharacter1 r){  assert (l.length == r.length);  *res = (memcmp (l.text, r.text, l.length) >= 0);  return FFEBAD;}#endif/* ffetarget_gt_character1 -- Perform relational comparison on char constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1ffebadffetarget_gt_character1 (bool *res, ffetargetCharacter1 l,			 ffetargetCharacter1 r){  assert (l.length == r.length);  *res = (memcmp (l.text, r.text, l.length) > 0);  return FFEBAD;}#endif#if FFETARGET_okCHARACTER1boolffetarget_iszero_character1 (ffetargetCharacter1 constant){  ffetargetCharacterSize i;  for (i = 0; i < constant.length; ++i)    if (constant.text[i] != 0)      return FALSE;  return TRUE;}#endifboolffetarget_iszero_hollerith (ffetargetHollerith constant){  ffetargetHollerithSize i;  for (i = 0; i < constant.length; ++i)    if (constant.text[i] != 0)      return FALSE;  return TRUE;}/* ffetarget_layout -- Do storage requirement analysis for entity   Return the alignment/modulo requirements along with the size, given the   data type info and the number of elements an array (1 for a scalar).	 */voidffetarget_layout (const char *error_text UNUSED, ffetargetAlign *alignment,		  ffetargetAlign *modulo, ffetargetOffset *size,		  ffeinfoBasictype bt, ffeinfoKindtype kt,		  ffetargetCharacterSize charsize,		  ffetargetIntegerDefault num_elements){  bool ok;			/* For character type. */  ffetargetOffset numele;	/* Converted from num_elements. */  ffetype type;  type = ffeinfo_type (bt, kt);  assert (type != NULL);  *alignment = ffetype_alignment (type);  *modulo = ffetype_modulo (type);  if (bt == FFEINFO_basictypeCHARACTER)    {      ok = ffetarget_offset_charsize (size, charsize, ffetype_size (type));#ifdef ffetarget_offset_overflow      if (!ok)	ffetarget_offset_overflow (error_text);#endif    }  else    *size = ffetype_size (type);  if ((num_elements < 0)      || !ffetarget_offset (&numele, num_elements)      || !ffetarget_offset_multiply (size, *size, numele))    {      ffetarget_offset_overflow (error_text);      *alignment = 1;      *modulo = 0;      *size = 0;    }}/* ffetarget_ne_character1 -- Perform relational comparison on char constants   Compare lengths, if equal then use memcmp.  */#if FFETARGET_okCHARACTER1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -