1169689Skan/* General Solaris system support.
2169689Skan   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3169689Skan   Contributed by CodeSourcery, LLC.
4169689Skan
5169689SkanThis file is part of GCC.
6169689Skan
7169689SkanGCC is free software; you can redistribute it and/or modify
8169689Skanit under the terms of the GNU General Public License as published by
9169689Skanthe Free Software Foundation; either version 2, or (at your option)
10169689Skanany later version.
11169689Skan
12169689SkanGCC is distributed in the hope that it will be useful,
13169689Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
14169689SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15169689SkanGNU General Public License for more details.
16169689Skan
17169689SkanYou should have received a copy of the GNU General Public License
18169689Skanalong with GCC; see the file COPYING.  If not, write to
19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor,
20169689SkanBoston, MA 02110-1301, USA.  */
21169689Skan
22169689Skan#include "config.h"
23169689Skan#include "system.h"
24169689Skan#include "coretypes.h"
25169689Skan#include "tree.h"
26169689Skan#include "tm.h"
27169689Skan#include "rtl.h"
28169689Skan#include "tm_p.h"
29169689Skan#include "toplev.h"
30169689Skan#include "ggc.h"
31169689Skan
32169689Skantree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
33169689Skan
34169689Skan/* Attach any pending attributes for DECL to the list in *ATTRIBUTES.
35169689Skan   Pending attributes come from #pragma or _Pragma, so this code is
36169689Skan   only useful in the C family front ends, but it is included in
37169689Skan   all languages to avoid changing the target machine initializer
38169689Skan   depending on the language.  */
39169689Skan
40169689Skanvoid
41169689Skansolaris_insert_attributes (tree decl, tree *attributes)
42169689Skan{
43169689Skan  tree *x, next;
44169689Skan
45169689Skan  if (solaris_pending_aligns != NULL && TREE_CODE (decl) == VAR_DECL)
46169689Skan    for (x = &solaris_pending_aligns; *x; x = &TREE_CHAIN (*x))
47169689Skan      {
48169689Skan	tree name = TREE_PURPOSE (*x);
49169689Skan	tree value = TREE_VALUE (*x);
50169689Skan	if (DECL_NAME (decl) == name)
51169689Skan	  {
52169689Skan	    if (lookup_attribute ("aligned", DECL_ATTRIBUTES (decl))
53169689Skan		|| lookup_attribute ("aligned", *attributes))
54169689Skan	      warning (0, "ignoring %<#pragma align%> for explicitly "
55169689Skan		       "aligned %q+D", decl);
56169689Skan	    else
57169689Skan	      *attributes = tree_cons (get_identifier ("aligned"), value,
58169689Skan				       *attributes);
59169689Skan	    next = TREE_CHAIN (*x);
60169689Skan	    ggc_free (*x);
61169689Skan	    *x = next;
62169689Skan	    break;
63169689Skan	  }
64169689Skan      }
65169689Skan
66169689Skan  if (solaris_pending_inits != NULL && TREE_CODE (decl) == FUNCTION_DECL)
67169689Skan    for (x = &solaris_pending_inits; *x; x = &TREE_CHAIN (*x))
68169689Skan      {
69169689Skan	tree name = TREE_PURPOSE (*x);
70169689Skan	if (DECL_NAME (decl) == name)
71169689Skan	  {
72169689Skan	    *attributes = tree_cons (get_identifier ("init"), NULL,
73169689Skan				     *attributes);
74169689Skan	    *attributes = tree_cons (get_identifier ("used"), NULL,
75169689Skan				     *attributes);
76169689Skan	    next = TREE_CHAIN (*x);
77169689Skan	    ggc_free (*x);
78169689Skan	    *x = next;
79169689Skan	    break;
80169689Skan	  }
81169689Skan      }
82169689Skan
83169689Skan  if (solaris_pending_finis != NULL && TREE_CODE (decl) == FUNCTION_DECL)
84169689Skan    for (x = &solaris_pending_finis; *x; x = &TREE_CHAIN (*x))
85169689Skan      {
86169689Skan	tree name = TREE_PURPOSE (*x);
87169689Skan	if (DECL_NAME (decl) == name)
88169689Skan	  {
89169689Skan	    *attributes = tree_cons (get_identifier ("fini"), NULL,
90169689Skan				     *attributes);
91169689Skan	    *attributes = tree_cons (get_identifier ("used"), NULL,
92169689Skan				     *attributes);
93169689Skan	    next = TREE_CHAIN (*x);
94169689Skan	    ggc_free (*x);
95169689Skan	    *x = next;
96169689Skan	    break;
97169689Skan	  }
98169689Skan      }
99169689Skan}
100169689Skan
101169689Skan/* Output initializer or finalizer entries for DECL to FILE.  */
102169689Skan
103169689Skanvoid
104169689Skansolaris_output_init_fini (FILE *file, tree decl)
105169689Skan{
106169689Skan  if (lookup_attribute ("init", DECL_ATTRIBUTES (decl)))
107169689Skan    {
108169689Skan      fprintf (file, "\t.pushsection\t\".init\"\n");
109169689Skan      ASM_OUTPUT_CALL (file, decl);
110169689Skan      fprintf (file, "\t.popsection\n");
111169689Skan    }
112169689Skan
113169689Skan  if (lookup_attribute ("fini", DECL_ATTRIBUTES (decl)))
114169689Skan    {
115169689Skan      fprintf (file, "\t.pushsection\t\".fini\"\n");
116169689Skan      ASM_OUTPUT_CALL (file, decl);
117169689Skan      fprintf (file, "\t.popsection\n");
118169689Skan    }
119169689Skan}
120169689Skan
121