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