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