OSDN Git Service

2010-09-18 Kai Tietz <kai.tietz@onevision.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / vxworks.c
1 /* Common VxWorks target definitions for GNU compiler.
2    Copyright (C) 2007, 2008, 2010
3    Free Software Foundation, Inc.
4    Contributed by CodeSourcery, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "target.h"
26 #include "diagnostic-core.h"
27 #include "toplev.h"
28 #include "output.h"
29 #include "tm.h"
30 #include "tree.h"
31
32 /* Like default_named_section_asm_out_constructor, except that even
33    constructors with DEFAULT_INIT_PRIORITY must go in a numbered
34    section on VxWorks.  The VxWorks runtime uses a clever trick to get
35    the sentinel entry (-1) inserted at the beginning of the .ctors
36    segment.  This trick will not work if we ever generate any entries
37    in plain .ctors sections; we must always use .ctors.PRIORITY.  */
38
39 void
40 vxworks_asm_out_constructor (rtx symbol, int priority)
41 {
42   section *sec;
43
44   sec = get_cdtor_priority_section (priority,
45                                     /*constructor_p=*/true);
46   assemble_addr_to_section (symbol, sec);
47 }
48
49 /* See comment for vxworks_asm_out_constructor.  */
50
51 void
52 vxworks_asm_out_destructor (rtx symbol, int priority)
53 {
54   section *sec;
55
56   sec = get_cdtor_priority_section (priority,
57                                     /*constructor_p=*/false);
58   assemble_addr_to_section (symbol, sec);
59 }
60
61 /* Return the list of FIELD_DECLs that make up an emulated TLS
62    variable's control object.  TYPE is the structure these are fields
63    of and *NAME will be filled in with the structure tag that should
64    be used.  */
65
66 static tree
67 vxworks_emutls_var_fields (tree type, tree *name)
68 {
69   tree field, next_field;
70   
71   *name = get_identifier ("__tls_var");
72   
73   field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
74                       get_identifier ("size"), unsigned_type_node);
75   DECL_CONTEXT (field) = type;
76   next_field = field;
77
78   field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
79                       get_identifier ("module_id"), unsigned_type_node);
80   DECL_CONTEXT (field) = type;
81   DECL_CHAIN (field) = next_field;
82   next_field = field;
83
84   field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
85                       get_identifier ("offset"), unsigned_type_node);
86   DECL_CONTEXT (field) = type;
87   DECL_CHAIN (field) = next_field;
88
89   return field;
90 }
91
92 /* Return the CONSTRUCTOR to initialize an emulated TLS control
93    object.  VAR is the control object.  DECL is the TLS object itself
94    and TMPL_ADDR is the address (an ADDR_EXPR) of the initializer for
95    that object.  */
96
97 static tree
98 vxworks_emutls_var_init (tree var, tree decl, tree tmpl_addr)
99 {
100   VEC(constructor_elt,gc) *v = VEC_alloc (constructor_elt, gc, 3);
101   constructor_elt *elt;
102   
103   tree type = TREE_TYPE (var);
104   tree field = TYPE_FIELDS (type);
105   
106   elt = VEC_quick_push (constructor_elt, v, NULL);
107   elt->index = field;
108   elt->value = fold_convert (TREE_TYPE (field), tmpl_addr);
109   
110   elt = VEC_quick_push (constructor_elt, v, NULL);
111   field = DECL_CHAIN (field);
112   elt->index = field;
113   elt->value = build_int_cst (TREE_TYPE (field), 0);
114   
115   elt = VEC_quick_push (constructor_elt, v, NULL);
116   field = DECL_CHAIN (field);
117   elt->index = field;
118   elt->value = fold_convert (TREE_TYPE (field), DECL_SIZE_UNIT (decl));
119   
120   return build_constructor (type, v);
121 }
122
123 /* Do VxWorks-specific parts of TARGET_OPTION_OVERRIDE.  */
124
125 void
126 vxworks_override_options (void)
127 {
128   /* We don't support __thread via target hooks.  */
129   targetm.have_tls = false;
130
131   targetm.emutls.get_address = "__builtin___tls_lookup";
132   targetm.emutls.register_common = NULL;
133   targetm.emutls.var_section = ".tls_vars";
134   targetm.emutls.tmpl_section = ".tls_data";
135   targetm.emutls.var_prefix = "__tls__";
136   targetm.emutls.tmpl_prefix = "";
137   targetm.emutls.var_fields = vxworks_emutls_var_fields;
138   targetm.emutls.var_init = vxworks_emutls_var_init;
139   targetm.emutls.var_align_fixed = true;
140   targetm.emutls.debug_form_tls_address = true;
141   
142   /* We can use .ctors/.dtors sections only in RTP mode.  */
143   targetm.have_ctors_dtors = TARGET_VXWORKS_RTP;
144
145   /* PIC is only supported for RTPs.  */
146   if (flag_pic && !TARGET_VXWORKS_RTP)
147     error ("PIC is only supported for RTPs");
148 }