OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [config/] [i386/] [netware.c] - Diff between revs 38 and 154

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 38 Rev 154
/* Subroutines for insn-output.c for NetWare.
/* Subroutines for insn-output.c for NetWare.
   Contributed by Jan Beulich (jbeulich@novell.com)
   Contributed by Jan Beulich (jbeulich@novell.com)
   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
the Free Software Foundation; either version 3, or (at your option)
any later version.
any later version.
 
 
GCC is distributed in the hope that it will be useful,
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "rtl.h"
#include "rtl.h"
#include "regs.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "hard-reg-set.h"
#include "output.h"
#include "output.h"
#include "tree.h"
#include "tree.h"
#include "flags.h"
#include "flags.h"
#include "tm_p.h"
#include "tm_p.h"
#include "toplev.h"
#include "toplev.h"
#include "ggc.h"
#include "ggc.h"
 
 
 
 
/* Return string which is the former assembler name modified with an
/* Return string which is the former assembler name modified with an
   underscore prefix and a suffix consisting of an atsign (@) followed
   underscore prefix and a suffix consisting of an atsign (@) followed
   by the number of bytes of arguments */
   by the number of bytes of arguments */
 
 
static tree
static tree
gen_stdcall_or_fastcall_decoration (tree decl, char prefix)
gen_stdcall_or_fastcall_decoration (tree decl, char prefix)
{
{
  unsigned total = 0;
  unsigned total = 0;
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
     of DECL_ASSEMBLER_NAME.  */
     of DECL_ASSEMBLER_NAME.  */
  const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  char *newsym;
  char *newsym;
  tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
  tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
 
 
  if (formal_type != NULL_TREE)
  if (formal_type != NULL_TREE)
    {
    {
      /* These attributes are ignored for variadic functions in
      /* These attributes are ignored for variadic functions in
         i386.c:ix86_return_pops_args. For compatibility with MS
         i386.c:ix86_return_pops_args. For compatibility with MS
         compiler do not add @0 suffix here.  */
         compiler do not add @0 suffix here.  */
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
        return NULL_TREE;
        return NULL_TREE;
 
 
      /* Quit if we hit an incomplete type.  Error is reported
      /* Quit if we hit an incomplete type.  Error is reported
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
      while (TREE_VALUE (formal_type) != void_type_node
      while (TREE_VALUE (formal_type) != void_type_node
             && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
             && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
        {
        {
          unsigned parm_size
          unsigned parm_size
            = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
            = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
 
 
          /* Must round up to include padding.  This is done the same
          /* Must round up to include padding.  This is done the same
             way as in store_one_arg.  */
             way as in store_one_arg.  */
          parm_size = ((parm_size + PARM_BOUNDARY - 1)
          parm_size = ((parm_size + PARM_BOUNDARY - 1)
                       / PARM_BOUNDARY * PARM_BOUNDARY);
                       / PARM_BOUNDARY * PARM_BOUNDARY);
          total += parm_size;
          total += parm_size;
          formal_type = TREE_CHAIN (formal_type);
          formal_type = TREE_CHAIN (formal_type);
        }
        }
    }
    }
 
 
  newsym = alloca (1 + strlen (asmname) + 1 + 10 + 1);
  newsym = alloca (1 + strlen (asmname) + 1 + 10 + 1);
  return get_identifier_with_length (newsym,
  return get_identifier_with_length (newsym,
                                     sprintf (newsym,
                                     sprintf (newsym,
                                              "%c%s@%u",
                                              "%c%s@%u",
                                              prefix,
                                              prefix,
                                              asmname,
                                              asmname,
                                              total / BITS_PER_UNIT));
                                              total / BITS_PER_UNIT));
}
}
 
 
/* Return string which is the former assembler name modified with an
/* Return string which is the former assembler name modified with an
   _n@ prefix where n represents the number of arguments passed in
   _n@ prefix where n represents the number of arguments passed in
   registers */
   registers */
 
 
static tree
static tree
gen_regparm_prefix (tree decl, unsigned nregs)
gen_regparm_prefix (tree decl, unsigned nregs)
{
{
  unsigned total = 0;
  unsigned total = 0;
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
     of DECL_ASSEMBLER_NAME.  */
     of DECL_ASSEMBLER_NAME.  */
  const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  char *newsym;
  char *newsym;
  tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
  tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
 
 
  if (formal_type != NULL_TREE)
  if (formal_type != NULL_TREE)
    {
    {
      /* This attribute is ignored for variadic functions.  */
      /* This attribute is ignored for variadic functions.  */
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
        return NULL_TREE;
        return NULL_TREE;
 
 
      /* Quit if we hit an incomplete type.  Error is reported
      /* Quit if we hit an incomplete type.  Error is reported
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
         by convert_arguments in c-typeck.c or cp/typeck.c.  */
      while (TREE_VALUE (formal_type) != void_type_node
      while (TREE_VALUE (formal_type) != void_type_node
             && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
             && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
        {
        {
          unsigned parm_size
          unsigned parm_size
            = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
            = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
 
 
          /* Must round up to include padding.  This is done the same
          /* Must round up to include padding.  This is done the same
             way as in store_one_arg.  */
             way as in store_one_arg.  */
          parm_size = ((parm_size + PARM_BOUNDARY - 1)
          parm_size = ((parm_size + PARM_BOUNDARY - 1)
                       / PARM_BOUNDARY * PARM_BOUNDARY);
                       / PARM_BOUNDARY * PARM_BOUNDARY);
          total += parm_size;
          total += parm_size;
          formal_type = TREE_CHAIN (formal_type);
          formal_type = TREE_CHAIN (formal_type);
        }
        }
    }
    }
 
 
  if (nregs > total / BITS_PER_WORD)
  if (nregs > total / BITS_PER_WORD)
    nregs = total / BITS_PER_WORD;
    nregs = total / BITS_PER_WORD;
  gcc_assert (nregs <= 9);
  gcc_assert (nregs <= 9);
  newsym = alloca (3 + strlen (asmname) + 1);
  newsym = alloca (3 + strlen (asmname) + 1);
  return get_identifier_with_length (newsym,
  return get_identifier_with_length (newsym,
                                     sprintf (newsym,
                                     sprintf (newsym,
                                              "_%u@%s",
                                              "_%u@%s",
                                              nregs,
                                              nregs,
                                              asmname));
                                              asmname));
}
}
 
 
void
void
i386_nlm_encode_section_info (tree decl, rtx rtl, int first)
i386_nlm_encode_section_info (tree decl, rtx rtl, int first)
{
{
  default_encode_section_info (decl, rtl, first);
  default_encode_section_info (decl, rtl, first);
 
 
  if (first
  if (first
      && TREE_CODE (decl) == FUNCTION_DECL
      && TREE_CODE (decl) == FUNCTION_DECL
      && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*'
      && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*'
      && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@'))
      && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@'))
    {
    {
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      tree newid;
      tree newid;
 
 
      if (lookup_attribute ("stdcall", type_attributes))
      if (lookup_attribute ("stdcall", type_attributes))
        newid = gen_stdcall_or_fastcall_decoration (decl, '_');
        newid = gen_stdcall_or_fastcall_decoration (decl, '_');
      else if (lookup_attribute ("fastcall", type_attributes))
      else if (lookup_attribute ("fastcall", type_attributes))
        newid = gen_stdcall_or_fastcall_decoration (decl, FASTCALL_PREFIX);
        newid = gen_stdcall_or_fastcall_decoration (decl, FASTCALL_PREFIX);
      else if ((newid = lookup_attribute ("regparm", type_attributes)) != NULL_TREE)
      else if ((newid = lookup_attribute ("regparm", type_attributes)) != NULL_TREE)
        newid = gen_regparm_prefix (decl,
        newid = gen_regparm_prefix (decl,
                      TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid))));
                      TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid))));
      if (newid != NULL_TREE)
      if (newid != NULL_TREE)
        {
        {
          rtx rtlname = XEXP (rtl, 0);
          rtx rtlname = XEXP (rtl, 0);
 
 
          if (GET_CODE (rtlname) == MEM)
          if (GET_CODE (rtlname) == MEM)
            rtlname = XEXP (rtlname, 0);
            rtlname = XEXP (rtlname, 0);
          XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
          XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
          /* These attributes must be present on first declaration,
          /* These attributes must be present on first declaration,
             change_decl_assembler_name will warn if they are added
             change_decl_assembler_name will warn if they are added
             later and the decl has been referenced, but duplicate_decls
             later and the decl has been referenced, but duplicate_decls
             should catch the mismatch before this is called.  */
             should catch the mismatch before this is called.  */
          change_decl_assembler_name (decl, newid);
          change_decl_assembler_name (decl, newid);
        }
        }
    }
    }
}
}
 
 
/* Strip the stdcall/fastcall/regparm pre-/suffix.  */
/* Strip the stdcall/fastcall/regparm pre-/suffix.  */
 
 
const char *
const char *
i386_nlm_strip_name_encoding (const char *str)
i386_nlm_strip_name_encoding (const char *str)
{
{
  const char *name = default_strip_name_encoding (str);
  const char *name = default_strip_name_encoding (str);
 
 
  if (*str != '*' && (*name == '_' || *name == '@'))
  if (*str != '*' && (*name == '_' || *name == '@'))
    {
    {
      const char *p = strchr (name + 1, '@');
      const char *p = strchr (name + 1, '@');
 
 
      if (p)
      if (p)
        {
        {
          ++name;
          ++name;
          if (ISDIGIT (p[1]))
          if (ISDIGIT (p[1]))
            name = ggc_alloc_string (name, p - name);
            name = ggc_alloc_string (name, p - name);
          else
          else
            {
            {
              gcc_assert (ISDIGIT (*name));
              gcc_assert (ISDIGIT (*name));
              name++;
              name++;
              gcc_assert (name == p);
              gcc_assert (name == p);
            }
            }
        }
        }
    }
    }
  return name;
  return name;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.