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