1 /* Pragma handling for GCC for Renesas / SuperH SH.
2    Copyright (C) 1993-2014 Free Software Foundation, Inc.
3    Contributed by Joern Rennecke <joern.rennecke@st.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 "tree.h"
26 #include "stringpool.h"
27 #include "attribs.h"
28 #include "tm_p.h"
29 #include "cpplib.h"
30 #include "c-family/c-common.h"
31 #include "target.h"
32 
33 /* Handle machine specific pragmas to be semi-compatible with Renesas
34    compiler.  */
35 
36 /* Add ATTR to the attributes of the current function.  If there is no
37    such function, save it to be added to the attributes of the next
38    function.  */
39 static void
sh_add_function_attribute(const char * attr)40 sh_add_function_attribute (const char *attr)
41 {
42   tree id = get_identifier (attr);
43 
44   if (current_function_decl)
45     decl_attributes (&current_function_decl,
46 		     tree_cons (id, NULL_TREE, NULL_TREE), 0);
47   else
48     {
49       *sh_deferred_function_attributes_tail
50 	= tree_cons (id, NULL_TREE, *sh_deferred_function_attributes_tail);
51       sh_deferred_function_attributes_tail
52 	= &TREE_CHAIN (*sh_deferred_function_attributes_tail);
53     }
54 }
55 
56 void
sh_pr_interrupt(struct cpp_reader * pfile ATTRIBUTE_UNUSED)57 sh_pr_interrupt (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
58 {
59   sh_add_function_attribute ("interrupt_handler");
60 }
61 
62 void
sh_pr_trapa(struct cpp_reader * pfile ATTRIBUTE_UNUSED)63 sh_pr_trapa (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
64 {
65   sh_add_function_attribute ("trapa_handler");
66 }
67 
68 void
sh_pr_nosave_low_regs(struct cpp_reader * pfile ATTRIBUTE_UNUSED)69 sh_pr_nosave_low_regs (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
70 {
71   sh_add_function_attribute ("nosave_low_regs");
72 }
73 
74 #define builtin_define(TXT) cpp_define (pfile, TXT)
75 #define builtin_assert(TXT) cpp_assert (pfile, TXT)
76 
77 /* Implement the TARGET_CPU_CPP_BUILTINS macro  */
78 void
sh_cpu_cpp_builtins(cpp_reader * pfile)79 sh_cpu_cpp_builtins (cpp_reader* pfile)
80 {
81   builtin_define ("__sh__");
82   builtin_assert ("cpu=sh");
83   builtin_assert ("machine=sh");
84   switch ((int) sh_cpu)
85     {
86     case PROCESSOR_SH1:
87       builtin_define ("__sh1__");
88       builtin_define ("__SH1__");
89       break;
90     case PROCESSOR_SH2:
91       builtin_define ("__sh2__");
92       builtin_define ("__SH2__");
93       break;
94     case PROCESSOR_SH2E:
95       builtin_define ("__SH2E__");
96       break;
97     case PROCESSOR_SH2A:
98       builtin_define ("__SH2A__");
99       if (TARGET_SH2A_DOUBLE)
100 	builtin_define (TARGET_FPU_SINGLE
101 			? "__SH2A_SINGLE__" : "__SH2A_DOUBLE__");
102       else
103 	builtin_define (TARGET_FPU_ANY
104 			? "__SH2A_SINGLE_ONLY__" : "__SH2A_NOFPU__");
105       break;
106     case PROCESSOR_SH3:
107       builtin_define ("__sh3__");
108       builtin_define ("__SH3__");
109       if (TARGET_HARD_SH4)
110 	builtin_define ("__SH4_NOFPU__");
111       break;
112     case PROCESSOR_SH3E:
113       builtin_define (TARGET_HARD_SH4 ? "__SH4_SINGLE_ONLY__" : "__SH3E__");
114       break;
115     case PROCESSOR_SH4:
116       builtin_define (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__");
117       break;
118     case PROCESSOR_SH4A: \
119       builtin_define ("__SH4A__");
120       builtin_define (TARGET_SH4
121 		      ? (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__")
122 		      : TARGET_FPU_ANY ? "__SH4_SINGLE_ONLY__"
123 		      : "__SH4_NOFPU__");
124       break;
125     case PROCESSOR_SH5:
126       {
127 	builtin_define_with_value ("__SH5__",
128 				   TARGET_SHMEDIA64 ? "64" : "32", 0);
129 	builtin_define_with_value ("__SHMEDIA__",
130 				   TARGET_SHMEDIA ? "1" : "0", 0);
131 	if (! TARGET_FPU_DOUBLE)
132 	  builtin_define ("__SH4_NOFPU__");
133       }
134     }
135   if (TARGET_FPU_ANY)
136     builtin_define ("__SH_FPU_ANY__");
137   if (TARGET_FPU_DOUBLE)
138     builtin_define ("__SH_FPU_DOUBLE__");
139   if (TARGET_HITACHI)
140     builtin_define ("__HITACHI__");
141   if (TARGET_FMOVD)
142     builtin_define ("__FMOVD_ENABLED__");
143   builtin_define (TARGET_LITTLE_ENDIAN
144 		  ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__");
145 
146   cpp_define_formatted (pfile, "__SH_ATOMIC_MODEL_%s__",
147 			selected_atomic_model ().cdef_name);
148 }
149