1 /* v850 specific, C compiler specific functions. 2 Copyright (C) 2000-2015 Free Software Foundation, Inc. 3 Contributed by Jeff Law (law@cygnus.com). 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "tm.h" 25 #include "cpplib.h" 26 #include "hash-set.h" 27 #include "machmode.h" 28 #include "vec.h" 29 #include "double-int.h" 30 #include "input.h" 31 #include "alias.h" 32 #include "symtab.h" 33 #include "wide-int.h" 34 #include "inchash.h" 35 #include "tree.h" 36 #include "stringpool.h" 37 #include "attribs.h" 38 #include "c-family/c-pragma.h" 39 #include "diagnostic-core.h" 40 #include "ggc.h" 41 #include "tm_p.h" 42 43 #ifndef streq 44 #define streq(a,b) (strcmp (a, b) == 0) 45 #endif 46 47 static int pop_data_area (v850_data_area); 48 static int push_data_area (v850_data_area); 49 static void mark_current_function_as_interrupt (void); 50 51 /* Push a data area onto the stack. */ 52 53 static int 54 push_data_area (v850_data_area data_area) 55 { 56 data_area_stack_element * elem; 57 58 elem = (data_area_stack_element *) xmalloc (sizeof (* elem)); 59 60 if (elem == NULL) 61 return 0; 62 63 elem->prev = data_area_stack; 64 elem->data_area = data_area; 65 66 data_area_stack = elem; 67 68 return 1; 69 } 70 71 /* Remove a data area from the stack. */ 72 73 static int 74 pop_data_area (v850_data_area data_area) 75 { 76 if (data_area_stack == NULL) 77 warning (OPT_Wpragmas, "#pragma GHS endXXXX found without " 78 "previous startXXX"); 79 else if (data_area != data_area_stack->data_area) 80 warning (OPT_Wpragmas, "#pragma GHS endXXX does not match " 81 "previous startXXX"); 82 else 83 { 84 data_area_stack_element * elem; 85 86 elem = data_area_stack; 87 data_area_stack = data_area_stack->prev; 88 89 free (elem); 90 91 return 1; 92 } 93 94 return 0; 95 } 96 97 /* Set the machine specific 'interrupt' attribute on the current function. */ 98 99 static void 100 mark_current_function_as_interrupt (void) 101 { 102 tree name; 103 104 if (current_function_decl == NULL_TREE) 105 { 106 warning (0, "cannot set interrupt attribute: no current function"); 107 return; 108 } 109 110 name = get_identifier ("interrupt"); 111 112 if (name == NULL_TREE || TREE_CODE (name) != IDENTIFIER_NODE) 113 { 114 warning (0, "cannot set interrupt attribute: no such identifier"); 115 return; 116 } 117 118 decl_attributes (¤t_function_decl, 119 tree_cons (name, NULL_TREE, NULL_TREE), 0); 120 } 121 122 123 /* Support for GHS pragmata. */ 124 125 void 126 ghs_pragma_section (cpp_reader * pfile ATTRIBUTE_UNUSED) 127 { 128 int repeat = 0; 129 130 /* #pragma ghs section [name = alias [, name = alias [, ...]]] */ 131 do 132 { 133 tree x; 134 enum cpp_ttype type; 135 tree sect_ident; 136 const char *sect, *alias; 137 enum GHS_section_kind kind; 138 139 type = pragma_lex (&x); 140 141 if (type == CPP_EOF && !repeat) 142 goto reset; 143 else if (type == CPP_NAME) 144 { 145 sect_ident = x; 146 sect = IDENTIFIER_POINTER (sect_ident); 147 } 148 else 149 goto bad; 150 repeat = 0; 151 152 if (pragma_lex (&x) != CPP_EQ) 153 goto bad; 154 if (pragma_lex (&x) != CPP_NAME) 155 goto bad; 156 157 alias = IDENTIFIER_POINTER (x); 158 159 type = pragma_lex (&x); 160 if (type == CPP_COMMA) 161 repeat = 1; 162 else if (type != CPP_EOF) 163 warning (OPT_Wpragmas, "junk at end of #pragma ghs section"); 164 165 if (streq (sect, "data")) kind = GHS_SECTION_KIND_DATA; 166 else if (streq (sect, "text")) kind = GHS_SECTION_KIND_TEXT; 167 else if (streq (sect, "rodata")) kind = GHS_SECTION_KIND_RODATA; 168 else if (streq (sect, "const")) kind = GHS_SECTION_KIND_RODATA; 169 else if (streq (sect, "rosdata")) kind = GHS_SECTION_KIND_ROSDATA; 170 else if (streq (sect, "rozdata")) kind = GHS_SECTION_KIND_ROZDATA; 171 else if (streq (sect, "sdata")) kind = GHS_SECTION_KIND_SDATA; 172 else if (streq (sect, "tdata")) kind = GHS_SECTION_KIND_TDATA; 173 else if (streq (sect, "zdata")) kind = GHS_SECTION_KIND_ZDATA; 174 /* According to GHS beta documentation, the following should not be 175 allowed! */ 176 else if (streq (sect, "bss")) kind = GHS_SECTION_KIND_BSS; 177 else if (streq (sect, "zbss")) kind = GHS_SECTION_KIND_ZDATA; 178 else 179 { 180 warning (0, "unrecognized section name %qE", sect_ident); 181 return; 182 } 183 184 if (streq (alias, "default")) 185 GHS_current_section_names [kind] = NULL; 186 else 187 GHS_current_section_names [kind] = alias; 188 } 189 while (repeat); 190 191 return; 192 193 bad: 194 warning (OPT_Wpragmas, "malformed #pragma ghs section"); 195 return; 196 197 reset: 198 /* #pragma ghs section \n: Reset all section names back to their defaults. */ 199 { 200 int i; 201 202 for (i = COUNT_OF_GHS_SECTION_KINDS; i--;) 203 GHS_current_section_names [i] = NULL; 204 } 205 } 206 207 void 208 ghs_pragma_interrupt (cpp_reader * pfile ATTRIBUTE_UNUSED) 209 { 210 tree x; 211 212 if (pragma_lex (&x) != CPP_EOF) 213 warning (OPT_Wpragmas, "junk at end of #pragma ghs interrupt"); 214 215 mark_current_function_as_interrupt (); 216 } 217 218 void 219 ghs_pragma_starttda (cpp_reader * pfile ATTRIBUTE_UNUSED) 220 { 221 tree x; 222 223 if (pragma_lex (&x) != CPP_EOF) 224 warning (OPT_Wpragmas, "junk at end of #pragma ghs starttda"); 225 226 push_data_area (DATA_AREA_TDA); 227 } 228 229 void 230 ghs_pragma_startsda (cpp_reader * pfile ATTRIBUTE_UNUSED) 231 { 232 tree x; 233 234 if (pragma_lex (&x) != CPP_EOF) 235 warning (OPT_Wpragmas, "junk at end of #pragma ghs startsda"); 236 237 push_data_area (DATA_AREA_SDA); 238 } 239 240 void 241 ghs_pragma_startzda (cpp_reader * pfile ATTRIBUTE_UNUSED) 242 { 243 tree x; 244 245 if (pragma_lex (&x) != CPP_EOF) 246 warning (OPT_Wpragmas, "junk at end of #pragma ghs startzda"); 247 248 push_data_area (DATA_AREA_ZDA); 249 } 250 251 void 252 ghs_pragma_endtda (cpp_reader * pfile ATTRIBUTE_UNUSED) 253 { 254 tree x; 255 256 if (pragma_lex (&x) != CPP_EOF) 257 warning (OPT_Wpragmas, "junk at end of #pragma ghs endtda"); 258 259 pop_data_area (DATA_AREA_TDA); 260 } 261 262 void 263 ghs_pragma_endsda (cpp_reader * pfile ATTRIBUTE_UNUSED) 264 { 265 tree x; 266 267 if (pragma_lex (&x) != CPP_EOF) 268 warning (OPT_Wpragmas, "junk at end of #pragma ghs endsda"); 269 270 pop_data_area (DATA_AREA_SDA); 271 } 272 273 void 274 ghs_pragma_endzda (cpp_reader * pfile ATTRIBUTE_UNUSED) 275 { 276 tree x; 277 278 if (pragma_lex (&x) != CPP_EOF) 279 warning (OPT_Wpragmas, "junk at end of #pragma ghs endzda"); 280 281 pop_data_area (DATA_AREA_ZDA); 282 } 283