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/] [arm/] [pe.c] - Diff between revs 38 and 154

Only display areas with differences | Details | Blame | View Log

Rev 38 Rev 154
/* Routines for GCC for ARM/pe.
/* Routines for GCC for ARM/pe.
   Copyright (C) 1995, 1996, 2000, 2001, 2002, 2004, 2005, 2007
   Copyright (C) 1995, 1996, 2000, 2001, 2002, 2004, 2005, 2007
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
   Contributed by Doug Evans (dje@cygnus.com).
   Contributed by Doug Evans (dje@cygnus.com).
 
 
   This file is part of GCC.
   This file is part of GCC.
 
 
   GCC is free software; you can redistribute it and/or modify it
   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published
   under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 3, or (at your
   by the Free Software Foundation; either version 3, or (at your
   option) any later version.
   option) any later version.
 
 
   GCC is distributed in the hope that it will be useful, but WITHOUT
   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.
   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 "output.h"
#include "output.h"
#include "flags.h"
#include "flags.h"
#include "tree.h"
#include "tree.h"
#include "expr.h"
#include "expr.h"
#include "toplev.h"
#include "toplev.h"
#include "tm_p.h"
#include "tm_p.h"
 
 
extern int current_function_anonymous_args;
extern int current_function_anonymous_args;
 
 


/* Return nonzero if DECL is a dllexport'd object.  */
/* Return nonzero if DECL is a dllexport'd object.  */
 
 
tree current_class_type; /* FIXME */
tree current_class_type; /* FIXME */
 
 
int
int
arm_dllexport_p (decl)
arm_dllexport_p (decl)
     tree decl;
     tree decl;
{
{
  tree exp;
  tree exp;
 
 
  if (TREE_CODE (decl) != VAR_DECL
  if (TREE_CODE (decl) != VAR_DECL
      && TREE_CODE (decl) != FUNCTION_DECL)
      && TREE_CODE (decl) != FUNCTION_DECL)
    return 0;
    return 0;
  exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
  exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
  if (exp)
  if (exp)
    return 1;
    return 1;
 
 
  return 0;
  return 0;
}
}
 
 
/* Return nonzero if DECL is a dllimport'd object.  */
/* Return nonzero if DECL is a dllimport'd object.  */
 
 
int
int
arm_dllimport_p (decl)
arm_dllimport_p (decl)
     tree decl;
     tree decl;
{
{
  tree imp;
  tree imp;
 
 
  if (TREE_CODE (decl) == FUNCTION_DECL
  if (TREE_CODE (decl) == FUNCTION_DECL
      && TARGET_NOP_FUN_DLLIMPORT)
      && TARGET_NOP_FUN_DLLIMPORT)
    return 0;
    return 0;
 
 
  if (TREE_CODE (decl) != VAR_DECL
  if (TREE_CODE (decl) != VAR_DECL
      && TREE_CODE (decl) != FUNCTION_DECL)
      && TREE_CODE (decl) != FUNCTION_DECL)
    return 0;
    return 0;
  imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
  imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
  if (imp)
  if (imp)
    return 1;
    return 1;
 
 
  return 0;
  return 0;
}
}
 
 
/* Return nonzero if SYMBOL is marked as being dllexport'd.  */
/* Return nonzero if SYMBOL is marked as being dllexport'd.  */
 
 
int
int
arm_dllexport_name_p (symbol)
arm_dllexport_name_p (symbol)
     const char * symbol;
     const char * symbol;
{
{
  return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'e' && symbol[2] == '.';
  return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'e' && symbol[2] == '.';
}
}
 
 
/* Return nonzero if SYMBOL is marked as being dllimport'd.  */
/* Return nonzero if SYMBOL is marked as being dllimport'd.  */
 
 
int
int
arm_dllimport_name_p (symbol)
arm_dllimport_name_p (symbol)
     const char * symbol;
     const char * symbol;
{
{
  return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'i' && symbol[2] == '.';
  return symbol[0] == ARM_PE_FLAG_CHAR && symbol[1] == 'i' && symbol[2] == '.';
}
}
 
 
/* Mark a DECL as being dllexport'd.
/* Mark a DECL as being dllexport'd.
   Note that we override the previous setting (e.g.: dllimport).  */
   Note that we override the previous setting (e.g.: dllimport).  */
 
 
void
void
arm_mark_dllexport (decl)
arm_mark_dllexport (decl)
     tree decl;
     tree decl;
{
{
  const char * oldname;
  const char * oldname;
  char * newname;
  char * newname;
  rtx rtlname;
  rtx rtlname;
  tree idp;
  tree idp;
 
 
  rtlname = XEXP (DECL_RTL (decl), 0);
  rtlname = XEXP (DECL_RTL (decl), 0);
  if (GET_CODE (rtlname) == MEM)
  if (GET_CODE (rtlname) == MEM)
    rtlname = XEXP (rtlname, 0);
    rtlname = XEXP (rtlname, 0);
  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
  oldname = XSTR (rtlname, 0);
  oldname = XSTR (rtlname, 0);
 
 
  if (arm_dllimport_name_p (oldname))
  if (arm_dllimport_name_p (oldname))
    oldname += 9;
    oldname += 9;
  else if (arm_dllexport_name_p (oldname))
  else if (arm_dllexport_name_p (oldname))
    return; /* already done */
    return; /* already done */
 
 
  newname = alloca (strlen (oldname) + 4);
  newname = alloca (strlen (oldname) + 4);
  sprintf (newname, "%ce.%s", ARM_PE_FLAG_CHAR, oldname);
  sprintf (newname, "%ce.%s", ARM_PE_FLAG_CHAR, oldname);
 
 
  /* We pass newname through get_identifier to ensure it has a unique
  /* We pass newname through get_identifier to ensure it has a unique
     address.  RTL processing can sometimes peek inside the symbol ref
     address.  RTL processing can sometimes peek inside the symbol ref
     and compare the string's addresses to see if two symbols are
     and compare the string's addresses to see if two symbols are
     identical.  */
     identical.  */
  /* ??? At least I think that's why we do this.  */
  /* ??? At least I think that's why we do this.  */
  idp = get_identifier (newname);
  idp = get_identifier (newname);
 
 
  XEXP (DECL_RTL (decl), 0) =
  XEXP (DECL_RTL (decl), 0) =
    gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
    gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
}
}
 
 
/* Mark a DECL as being dllimport'd.  */
/* Mark a DECL as being dllimport'd.  */
 
 
void
void
arm_mark_dllimport (decl)
arm_mark_dllimport (decl)
     tree decl;
     tree decl;
{
{
  const char * oldname;
  const char * oldname;
  char * newname;
  char * newname;
  tree idp;
  tree idp;
  rtx rtlname, newrtl;
  rtx rtlname, newrtl;
 
 
  rtlname = XEXP (DECL_RTL (decl), 0);
  rtlname = XEXP (DECL_RTL (decl), 0);
 
 
  if (GET_CODE (rtlname) == MEM)
  if (GET_CODE (rtlname) == MEM)
    rtlname = XEXP (rtlname, 0);
    rtlname = XEXP (rtlname, 0);
  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
  gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
  oldname = XSTR (rtlname, 0);
  oldname = XSTR (rtlname, 0);
 
 
  gcc_assert (!arm_dllexport_name_p (oldname));
  gcc_assert (!arm_dllexport_name_p (oldname));
  if (arm_dllimport_name_p (oldname))
  if (arm_dllimport_name_p (oldname))
    return; /* already done */
    return; /* already done */
 
 
  /* ??? One can well ask why we're making these checks here,
  /* ??? One can well ask why we're making these checks here,
     and that would be a good question.  */
     and that would be a good question.  */
 
 
  /* Imported variables can't be initialized.  */
  /* Imported variables can't be initialized.  */
  if (TREE_CODE (decl) == VAR_DECL
  if (TREE_CODE (decl) == VAR_DECL
      && !DECL_VIRTUAL_P (decl)
      && !DECL_VIRTUAL_P (decl)
      && DECL_INITIAL (decl))
      && DECL_INITIAL (decl))
    {
    {
      error ("initialized variable %q+D is marked dllimport", decl);
      error ("initialized variable %q+D is marked dllimport", decl);
      return;
      return;
    }
    }
  /* Nor can they be static.  */
  /* Nor can they be static.  */
  if (TREE_CODE (decl) == VAR_DECL
  if (TREE_CODE (decl) == VAR_DECL
      /* ??? Is this test for vtables needed?  */
      /* ??? Is this test for vtables needed?  */
      && !DECL_VIRTUAL_P (decl)
      && !DECL_VIRTUAL_P (decl)
      && 0 /*???*/)
      && 0 /*???*/)
    {
    {
      error ("static variable %q+D is marked dllimport", decl);
      error ("static variable %q+D is marked dllimport", decl);
      return;
      return;
    }
    }
 
 
  /* `extern' needn't be specified with dllimport.
  /* `extern' needn't be specified with dllimport.
     Specify `extern' now and hope for the best.  Sigh.  */
     Specify `extern' now and hope for the best.  Sigh.  */
  if (TREE_CODE (decl) == VAR_DECL
  if (TREE_CODE (decl) == VAR_DECL
      /* ??? Is this test for vtables needed?  */
      /* ??? Is this test for vtables needed?  */
      && !DECL_VIRTUAL_P (decl))
      && !DECL_VIRTUAL_P (decl))
    {
    {
      DECL_EXTERNAL (decl) = 1;
      DECL_EXTERNAL (decl) = 1;
      TREE_PUBLIC (decl) = 1;
      TREE_PUBLIC (decl) = 1;
    }
    }
 
 
  newname = alloca (strlen (oldname) + 11);
  newname = alloca (strlen (oldname) + 11);
  sprintf (newname, "%ci.__imp_%s", ARM_PE_FLAG_CHAR, oldname);
  sprintf (newname, "%ci.__imp_%s", ARM_PE_FLAG_CHAR, oldname);
 
 
  /* We pass newname through get_identifier to ensure it has a unique
  /* We pass newname through get_identifier to ensure it has a unique
     address.  RTL processing can sometimes peek inside the symbol ref
     address.  RTL processing can sometimes peek inside the symbol ref
     and compare the string's addresses to see if two symbols are
     and compare the string's addresses to see if two symbols are
     identical.  */
     identical.  */
  /* ??? At least I think that's why we do this.  */
  /* ??? At least I think that's why we do this.  */
  idp = get_identifier (newname);
  idp = get_identifier (newname);
 
 
  newrtl = gen_rtx_MEM (Pmode,
  newrtl = gen_rtx_MEM (Pmode,
                        gen_rtx_SYMBOL_REF (Pmode,
                        gen_rtx_SYMBOL_REF (Pmode,
                                            IDENTIFIER_POINTER (idp)));
                                            IDENTIFIER_POINTER (idp)));
  XEXP (DECL_RTL (decl), 0) = newrtl;
  XEXP (DECL_RTL (decl), 0) = newrtl;
}
}
 
 
void
void
arm_pe_encode_section_info (decl, rtl, first)
arm_pe_encode_section_info (decl, rtl, first)
     tree decl;
     tree decl;
     rtx rtl;
     rtx rtl;
     int first ATTRIBUTE_UNUSED;
     int first ATTRIBUTE_UNUSED;
{
{
  /* This bit is copied from arm_encode_section_info.  */
  /* This bit is copied from arm_encode_section_info.  */
  if (optimize > 0 && TREE_CONSTANT (decl))
  if (optimize > 0 && TREE_CONSTANT (decl))
    SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
    SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
 
 
  /* Mark the decl so we can tell from the rtl whether the object is
  /* Mark the decl so we can tell from the rtl whether the object is
     dllexport'd or dllimport'd.  */
     dllexport'd or dllimport'd.  */
  if (arm_dllexport_p (decl))
  if (arm_dllexport_p (decl))
    arm_mark_dllexport (decl);
    arm_mark_dllexport (decl);
  else if (arm_dllimport_p (decl))
  else if (arm_dllimport_p (decl))
    arm_mark_dllimport (decl);
    arm_mark_dllimport (decl);
  /* It might be that DECL has already been marked as dllimport, but a
  /* It might be that DECL has already been marked as dllimport, but a
     subsequent definition nullified that.  The attribute is gone but
     subsequent definition nullified that.  The attribute is gone but
     DECL_RTL still has @i.__imp_foo.  We need to remove that.  */
     DECL_RTL still has @i.__imp_foo.  We need to remove that.  */
  else if ((TREE_CODE (decl) == FUNCTION_DECL
  else if ((TREE_CODE (decl) == FUNCTION_DECL
            || TREE_CODE (decl) == VAR_DECL)
            || TREE_CODE (decl) == VAR_DECL)
           && DECL_RTL (decl) != NULL_RTX
           && DECL_RTL (decl) != NULL_RTX
           && GET_CODE (DECL_RTL (decl)) == MEM
           && GET_CODE (DECL_RTL (decl)) == MEM
           && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
           && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
           && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
           && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
           && arm_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
           && arm_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
    {
    {
      const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
      const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
      tree idp = get_identifier (oldname + 9);
      tree idp = get_identifier (oldname + 9);
      rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
      rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
 
 
      XEXP (DECL_RTL (decl), 0) = newrtl;
      XEXP (DECL_RTL (decl), 0) = newrtl;
 
 
      /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
      /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
         ??? We leave these alone for now.  */
         ??? We leave these alone for now.  */
    }
    }
}
}
 
 
void
void
arm_pe_unique_section (decl, reloc)
arm_pe_unique_section (decl, reloc)
     tree decl;
     tree decl;
     int reloc;
     int reloc;
{
{
  int len;
  int len;
  const char * name;
  const char * name;
  char * string;
  char * string;
  const char * prefix;
  const char * prefix;
 
 
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  name = arm_strip_name_encoding (name);
  name = arm_strip_name_encoding (name);
 
 
  /* The object is put in, for example, section .text$foo.
  /* The object is put in, for example, section .text$foo.
     The linker will then ultimately place them in .text
     The linker will then ultimately place them in .text
     (everything from the $ on is stripped).  */
     (everything from the $ on is stripped).  */
  if (TREE_CODE (decl) == FUNCTION_DECL)
  if (TREE_CODE (decl) == FUNCTION_DECL)
    prefix = ".text$";
    prefix = ".text$";
  else if (decl_readonly_section (decl, reloc))
  else if (decl_readonly_section (decl, reloc))
    prefix = ".rdata$";
    prefix = ".rdata$";
  else
  else
    prefix = ".data$";
    prefix = ".data$";
  len = strlen (name) + strlen (prefix);
  len = strlen (name) + strlen (prefix);
  string = alloca (len + 1);
  string = alloca (len + 1);
  sprintf (string, "%s%s", prefix, name);
  sprintf (string, "%s%s", prefix, name);
 
 
  DECL_SECTION_NAME (decl) = build_string (len, string);
  DECL_SECTION_NAME (decl) = build_string (len, string);
}
}
 
 

powered by: WebSVN 2.1.0

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