1 /* Common hooks for Blackfin.
2    Copyright (C) 2005-2016 Free Software Foundation, Inc.
3 
4    This file is part of GCC.
5 
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published
8    by the Free Software Foundation; either version 3, or (at your
9    option) any later version.
10 
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "diagnostic-core.h"
24 #include "tm.h"
25 #include "tm_p.h"
26 #include "common/common-target.h"
27 #include "common/common-target-def.h"
28 #include "opts.h"
29 #include "flags.h"
30 
31 EXPORTED_CONST struct bfin_cpu bfin_cpus[] =
32 {
33 
34   {"bf512", BFIN_CPU_BF512, 0x0002,
35    WA_SPECULATIVE_LOADS | WA_05000074},
36   {"bf512", BFIN_CPU_BF512, 0x0001,
37    WA_SPECULATIVE_LOADS | WA_05000074},
38   {"bf512", BFIN_CPU_BF512, 0x0000,
39    WA_SPECULATIVE_LOADS | WA_05000074},
40 
41   {"bf514", BFIN_CPU_BF514, 0x0002,
42    WA_SPECULATIVE_LOADS | WA_05000074},
43   {"bf514", BFIN_CPU_BF514, 0x0001,
44    WA_SPECULATIVE_LOADS | WA_05000074},
45   {"bf514", BFIN_CPU_BF514, 0x0000,
46    WA_SPECULATIVE_LOADS | WA_05000074},
47 
48   {"bf516", BFIN_CPU_BF516, 0x0002,
49    WA_SPECULATIVE_LOADS | WA_05000074},
50   {"bf516", BFIN_CPU_BF516, 0x0001,
51    WA_SPECULATIVE_LOADS | WA_05000074},
52   {"bf516", BFIN_CPU_BF516, 0x0000,
53    WA_SPECULATIVE_LOADS | WA_05000074},
54 
55   {"bf518", BFIN_CPU_BF518, 0x0002,
56    WA_SPECULATIVE_LOADS | WA_05000074},
57   {"bf518", BFIN_CPU_BF518, 0x0001,
58    WA_SPECULATIVE_LOADS | WA_05000074},
59   {"bf518", BFIN_CPU_BF518, 0x0000,
60    WA_SPECULATIVE_LOADS | WA_05000074},
61 
62   {"bf522", BFIN_CPU_BF522, 0x0002,
63    WA_SPECULATIVE_LOADS | WA_05000074},
64   {"bf522", BFIN_CPU_BF522, 0x0001,
65    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
66   {"bf522", BFIN_CPU_BF522, 0x0000,
67    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
68 
69   {"bf523", BFIN_CPU_BF523, 0x0002,
70    WA_SPECULATIVE_LOADS | WA_05000074},
71   {"bf523", BFIN_CPU_BF523, 0x0001,
72    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
73   {"bf523", BFIN_CPU_BF523, 0x0000,
74    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
75 
76   {"bf524", BFIN_CPU_BF524, 0x0002,
77    WA_SPECULATIVE_LOADS | WA_05000074},
78   {"bf524", BFIN_CPU_BF524, 0x0001,
79    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
80   {"bf524", BFIN_CPU_BF524, 0x0000,
81    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
82 
83   {"bf525", BFIN_CPU_BF525, 0x0002,
84    WA_SPECULATIVE_LOADS | WA_05000074},
85   {"bf525", BFIN_CPU_BF525, 0x0001,
86    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
87   {"bf525", BFIN_CPU_BF525, 0x0000,
88    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
89 
90   {"bf526", BFIN_CPU_BF526, 0x0002,
91    WA_SPECULATIVE_LOADS | WA_05000074},
92   {"bf526", BFIN_CPU_BF526, 0x0001,
93    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
94   {"bf526", BFIN_CPU_BF526, 0x0000,
95    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
96 
97   {"bf527", BFIN_CPU_BF527, 0x0002,
98    WA_SPECULATIVE_LOADS | WA_05000074},
99   {"bf527", BFIN_CPU_BF527, 0x0001,
100    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
101   {"bf527", BFIN_CPU_BF527, 0x0000,
102    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000074},
103 
104   {"bf531", BFIN_CPU_BF531, 0x0006,
105    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
106   {"bf531", BFIN_CPU_BF531, 0x0005,
107    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
108    | WA_LOAD_LCREGS | WA_05000074},
109   {"bf531", BFIN_CPU_BF531, 0x0004,
110    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
111    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
112    | WA_05000074},
113   {"bf531", BFIN_CPU_BF531, 0x0003,
114    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
115    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
116    | WA_05000074},
117 
118   {"bf532", BFIN_CPU_BF532, 0x0006,
119    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
120   {"bf532", BFIN_CPU_BF532, 0x0005,
121    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
122    | WA_LOAD_LCREGS | WA_05000074},
123   {"bf532", BFIN_CPU_BF532, 0x0004,
124    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
125    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
126    | WA_05000074},
127   {"bf532", BFIN_CPU_BF532, 0x0003,
128    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
129    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
130    | WA_05000074},
131 
132   {"bf533", BFIN_CPU_BF533, 0x0006,
133    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
134   {"bf533", BFIN_CPU_BF533, 0x0005,
135    WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315
136    | WA_LOAD_LCREGS | WA_05000074},
137   {"bf533", BFIN_CPU_BF533, 0x0004,
138    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
139    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
140    | WA_05000074},
141   {"bf533", BFIN_CPU_BF533, 0x0003,
142    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
143    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
144    | WA_05000074},
145 
146   {"bf534", BFIN_CPU_BF534, 0x0003,
147    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
148   {"bf534", BFIN_CPU_BF534, 0x0002,
149    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
150    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
151    | WA_05000074},
152   {"bf534", BFIN_CPU_BF534, 0x0001,
153    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
154    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
155    | WA_05000074},
156 
157   {"bf536", BFIN_CPU_BF536, 0x0003,
158    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
159   {"bf536", BFIN_CPU_BF536, 0x0002,
160    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
161    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
162    | WA_05000074},
163   {"bf536", BFIN_CPU_BF536, 0x0001,
164    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
165    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
166    | WA_05000074},
167 
168   {"bf537", BFIN_CPU_BF537, 0x0003,
169    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
170   {"bf537", BFIN_CPU_BF537, 0x0002,
171    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
172    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
173    | WA_05000074},
174   {"bf537", BFIN_CPU_BF537, 0x0001,
175    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
176    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
177    | WA_05000074},
178 
179   {"bf538", BFIN_CPU_BF538, 0x0005,
180    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
181   {"bf538", BFIN_CPU_BF538, 0x0004,
182    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
183   {"bf538", BFIN_CPU_BF538, 0x0003,
184    WA_SPECULATIVE_LOADS | WA_RETS
185    | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
186   {"bf538", BFIN_CPU_BF538, 0x0002,
187    WA_SPECULATIVE_LOADS | WA_RETS
188    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
189    | WA_05000074},
190 
191   {"bf539", BFIN_CPU_BF539, 0x0005,
192    WA_SPECULATIVE_LOADS | WA_LOAD_LCREGS | WA_05000074},
193   {"bf539", BFIN_CPU_BF539, 0x0004,
194    WA_SPECULATIVE_LOADS | WA_RETS | WA_LOAD_LCREGS | WA_05000074},
195   {"bf539", BFIN_CPU_BF539, 0x0003,
196    WA_SPECULATIVE_LOADS | WA_RETS
197    | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
198   {"bf539", BFIN_CPU_BF539, 0x0002,
199    WA_SPECULATIVE_LOADS | WA_RETS
200    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
201    | WA_05000074},
202 
203   {"bf542m", BFIN_CPU_BF542M, 0x0003,
204    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
205 
206   {"bf542", BFIN_CPU_BF542, 0x0004,
207    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
208   {"bf542", BFIN_CPU_BF542, 0x0002,
209    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
210   {"bf542", BFIN_CPU_BF542, 0x0001,
211    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
212   {"bf542", BFIN_CPU_BF542, 0x0000,
213    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
214    | WA_05000074},
215 
216   {"bf544m", BFIN_CPU_BF544M, 0x0003,
217    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
218 
219   {"bf544", BFIN_CPU_BF544, 0x0004,
220    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
221   {"bf544", BFIN_CPU_BF544, 0x0002,
222    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
223   {"bf544", BFIN_CPU_BF544, 0x0001,
224    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
225   {"bf544", BFIN_CPU_BF544, 0x0000,
226    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
227    | WA_05000074},
228 
229   {"bf547m", BFIN_CPU_BF547M, 0x0003,
230    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
231 
232   {"bf547", BFIN_CPU_BF547, 0x0004,
233    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
234   {"bf547", BFIN_CPU_BF547, 0x0002,
235    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
236   {"bf547", BFIN_CPU_BF547, 0x0001,
237    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
238   {"bf547", BFIN_CPU_BF547, 0x0000,
239    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
240    | WA_05000074},
241 
242   {"bf548m", BFIN_CPU_BF548M, 0x0003,
243    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
244 
245   {"bf548", BFIN_CPU_BF548, 0x0004,
246    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
247   {"bf548", BFIN_CPU_BF548, 0x0002,
248    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
249   {"bf548", BFIN_CPU_BF548, 0x0001,
250    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
251   {"bf548", BFIN_CPU_BF548, 0x0000,
252    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
253    | WA_05000074},
254 
255   {"bf549m", BFIN_CPU_BF549M, 0x0003,
256    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
257 
258   {"bf549", BFIN_CPU_BF549, 0x0004,
259    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
260   {"bf549", BFIN_CPU_BF549, 0x0002,
261    WA_SPECULATIVE_LOADS | WA_INDIRECT_CALLS | WA_05000074},
262   {"bf549", BFIN_CPU_BF549, 0x0001,
263    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_05000074},
264   {"bf549", BFIN_CPU_BF549, 0x0000,
265    WA_SPECULATIVE_LOADS | WA_RETS | WA_INDIRECT_CALLS | WA_LOAD_LCREGS
266    | WA_05000074},
267 
268   {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS
269    | WA_05000283 | WA_05000315 | WA_LOAD_LCREGS | WA_05000074},
270   {"bf561", BFIN_CPU_BF561, 0x0003,
271    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
272    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
273    | WA_05000074},
274   {"bf561", BFIN_CPU_BF561, 0x0002,
275    WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS
276    | WA_05000283 | WA_05000257 | WA_05000315 | WA_LOAD_LCREGS
277    | WA_05000074},
278 
279   {"bf592", BFIN_CPU_BF592, 0x0001,
280    WA_SPECULATIVE_LOADS | WA_05000074},
281   {"bf592", BFIN_CPU_BF592, 0x0000,
282    WA_SPECULATIVE_LOADS | WA_05000074},
283 
284   {NULL, BFIN_CPU_UNKNOWN, 0, 0}
285 };
286 
287 /* Implement TARGET_HANDLE_OPTION.  */
288 
289 static bool
bfin_handle_option(struct gcc_options * opts,struct gcc_options * opts_set ATTRIBUTE_UNUSED,const struct cl_decoded_option * decoded,location_t loc)290 bfin_handle_option (struct gcc_options *opts,
291 		    struct gcc_options *opts_set ATTRIBUTE_UNUSED,
292 		    const struct cl_decoded_option *decoded,
293 		    location_t loc)
294 {
295   size_t code = decoded->opt_index;
296   const char *arg = decoded->arg;
297   int value = decoded->value;
298 
299   switch (code)
300     {
301     case OPT_mshared_library_id_:
302       if (value > MAX_LIBRARY_ID)
303 	error_at (loc, "-mshared-library-id=%s is not between 0 and %d",
304 		  arg, MAX_LIBRARY_ID);
305       return true;
306 
307     case OPT_mcpu_:
308       {
309 	const char *p, *q;
310 	int i;
311 
312 	i = 0;
313 	while ((p = bfin_cpus[i].name) != NULL)
314 	  {
315 	    if (strncmp (arg, p, strlen (p)) == 0)
316 	      break;
317 	    i++;
318 	  }
319 
320 	if (p == NULL)
321 	  {
322 	    error_at (loc, "-mcpu=%s is not valid", arg);
323 	    return false;
324 	  }
325 
326 	opts->x_bfin_cpu_type = bfin_cpus[i].type;
327 
328 	q = arg + strlen (p);
329 
330 	if (*q == '\0')
331 	  {
332 	    opts->x_bfin_si_revision = bfin_cpus[i].si_revision;
333 	    opts->x_bfin_workarounds |= bfin_cpus[i].workarounds;
334 	  }
335 	else if (strcmp (q, "-none") == 0)
336 	  opts->x_bfin_si_revision = -1;
337       	else if (strcmp (q, "-any") == 0)
338 	  {
339 	    opts->x_bfin_si_revision = 0xffff;
340 	    while (bfin_cpus[i].type == opts->x_bfin_cpu_type)
341 	      {
342 		opts->x_bfin_workarounds |= bfin_cpus[i].workarounds;
343 		i++;
344 	      }
345 	  }
346 	else
347 	  {
348 	    unsigned int si_major, si_minor;
349 	    int rev_len, n;
350 
351 	    rev_len = strlen (q);
352 
353 	    if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2
354 		|| n != rev_len
355 		|| si_major > 0xff || si_minor > 0xff)
356 	      {
357 	      invalid_silicon_revision:
358 		error_at (loc, "-mcpu=%s has invalid silicon revision", arg);
359 		return false;
360 	      }
361 
362 	    opts->x_bfin_si_revision = (si_major << 8) | si_minor;
363 
364 	    while (bfin_cpus[i].type == opts->x_bfin_cpu_type
365 		   && bfin_cpus[i].si_revision != opts->x_bfin_si_revision)
366 	      i++;
367 
368 	    if (bfin_cpus[i].type != opts->x_bfin_cpu_type)
369 	      goto invalid_silicon_revision;
370 
371 	    opts->x_bfin_workarounds |= bfin_cpus[i].workarounds;
372 	  }
373 
374 	return true;
375       }
376 
377     default:
378       return true;
379     }
380 }
381 
382 #undef TARGET_HANDLE_OPTION
383 #define TARGET_HANDLE_OPTION bfin_handle_option
384 
385 #undef TARGET_DEFAULT_TARGET_FLAGS
386 #define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
387 
388 struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;
389