1 /* M32C Pragma support 2 Copyright (C) 2004-2019 Free Software Foundation, Inc. 3 Contributed by Red Hat, Inc. 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 #define IN_TARGET_CODE 1 22 23 #include "config.h" 24 #include "system.h" 25 #include "coretypes.h" 26 #include "tm.h" 27 #include "c-family/c-common.h" 28 #include "c-family/c-pragma.h" 29 #include "m32c-protos.h" 30 31 /* Implements the "GCC memregs" pragma. This pragma takes only an 32 integer, and is semantically identical to the -memregs= command 33 line option. The only catch is, the programmer should only use 34 this pragma at the beginning of the file (preferably, in some 35 project-wide header) to avoid ABI changes related to changing the 36 list of available "registers". */ 37 static void 38 m32c_pragma_memregs (cpp_reader * reader ATTRIBUTE_UNUSED) 39 { 40 /* on off */ 41 tree val; 42 enum cpp_ttype type; 43 HOST_WIDE_INT i; 44 45 type = pragma_lex (&val); 46 if (type == CPP_NUMBER) 47 { 48 if (tree_fits_uhwi_p (val)) 49 { 50 i = tree_to_uhwi (val); 51 52 type = pragma_lex (&val); 53 if (type != CPP_EOF) 54 warning (0, "junk at end of #pragma GCC memregs [0..16]"); 55 56 if (i >= 0 && i <= 16) 57 { 58 if (!ok_to_change_target_memregs) 59 { 60 warning (0, 61 "#pragma GCC memregs must precede any function decls"); 62 return; 63 } 64 target_memregs = i; 65 m32c_conditional_register_usage (); 66 } 67 else 68 { 69 warning (0, "#pragma GCC memregs takes a number [0..16]"); 70 } 71 72 return; 73 } 74 } 75 76 error ("#pragma GCC memregs takes a number [0..16]"); 77 } 78 79 /* Implements the "pragma ADDRESS" pragma. This pragma takes a 80 variable name and an address, and arranges for that variable to be 81 "at" that address. The variable is also made volatile. */ 82 static void 83 m32c_pragma_address (cpp_reader * reader ATTRIBUTE_UNUSED) 84 { 85 /* on off */ 86 tree var, addr; 87 enum cpp_ttype type; 88 89 type = pragma_lex (&var); 90 if (type == CPP_NAME) 91 { 92 type = pragma_lex (&addr); 93 if (type == CPP_NUMBER) 94 { 95 if (var != error_mark_node) 96 { 97 unsigned uaddr = tree_to_uhwi (addr); 98 m32c_note_pragma_address (IDENTIFIER_POINTER (var), uaddr); 99 } 100 101 type = pragma_lex (&var); 102 if (type != CPP_EOF) 103 { 104 error ("junk at end of #pragma ADDRESS"); 105 } 106 return; 107 } 108 } 109 error ("malformed #pragma ADDRESS variable address"); 110 } 111 112 /* Implements REGISTER_TARGET_PRAGMAS. */ 113 void 114 m32c_register_pragmas (void) 115 { 116 c_register_pragma ("GCC", "memregs", m32c_pragma_memregs); 117 c_register_pragma (NULL, "ADDRESS", m32c_pragma_address); 118 c_register_pragma (NULL, "address", m32c_pragma_address); 119 120 /* R8C and M16C have 16-bit pointers in a 20-bit address zpace. 121 M32C has 24-bit pointers in a 24-bit address space, so does not 122 need far pointers, but we accept the qualifier anyway, as a 123 no-op. */ 124 if (TARGET_A16) 125 c_register_addr_space ("__far", ADDR_SPACE_FAR); 126 else 127 c_register_addr_space ("__far", ADDR_SPACE_GENERIC); 128 } 129