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