1 /* Subroutines used for reading MCU data on TI MSP430 processors.
2    Copyright (C) 2019-2020 Free Software Foundation, Inc.
3    Contributed by Jozef Lawrynowicz  <jozef.l@mittosystems.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 "backend.h"
25 #include "target.h"
26 #include "tree.h"
27 #include "memmodel.h"
28 #include "diagnostic-core.h"
29 #include "langhooks.h"
30 #include "builtins.h"
31 #include "intl.h"
32 #include "msp430-devices.h"
33 
34 struct t_msp430_mcu_data extracted_mcu_data;
35 /* Initialized at the bottom of this file.  */
36 extern struct t_msp430_mcu_data hard_msp430_mcu_data[605];
37 
38 /* Set to the full path to devices.csv if it is found by searching the -I and
39    -L paths.  */
40 char *derived_devices_csv_loc = NULL;
41 
42 /* This is to canonicalize the directory separators in the path.
43    On Windows we could have a mix of '/' and '\' in the path.  */
44 static void
canonicalize_path_dirsep(char ** path)45 canonicalize_path_dirsep (char **path)
46 {
47   char *t_path = *path;
48   int len = strlen (t_path);
49   int i;
50   for (i = 0; i < len; i++)
51     if (IS_DIR_SEPARATOR (t_path[i]))
52       t_path[i] = DIR_SEPARATOR;
53 }
54 
55 /* This function returns the enclosing directory of PATH.
56    It is inconsequential whether PATH ends in a dirsep or not.
57    It modifies the string pointed to by PATH.  */
58 char *
msp430_dirname(char * path)59 msp430_dirname (char *path)
60 {
61   int last_elem = strlen (path) - 1;
62   int i = last_elem - (IS_DIR_SEPARATOR (path[last_elem]) ? 1 : 0);
63   for (; i >= 0; i--)
64     {
65       if (IS_DIR_SEPARATOR (path[i]))
66 	{
67 	  path[i] = '\0';
68 	  return path;
69 	}
70     }
71   return path;
72 }
73 
74 /* We need to support both the msp430-elf and msp430-elfbare target aliases.
75    gcc/config/msp430/t-msp430 will define TARGET_SUBDIR to the target_subdir
76    Makefile variable, which will evaluate to the correct subdirectory that
77    needs to be searched for devices.csv.  */
78 #ifndef TARGET_SUBDIR
79 #define TARGET_SUBDIR msp430-elf
80 #endif
81 
82 #define _MSPMKSTR(x) __MSPMKSTR(x)
83 #define __MSPMKSTR(x) #x
84 
85 /* devices.csv path from the toolchain root.  */
86 static const char rest_of_devices_path[] =
87   "/" _MSPMKSTR (TARGET_SUBDIR) "/include/devices/";
88 
89 #undef _MSPMKSTR
90 #undef __MSPMKSTR
91 
92 /* "The default value of GCC_EXEC_PREFIX is prefix/lib/gcc". Strip lib/gcc
93    from GCC_EXEC_PREFIX to get the path to the installed toolchain.  */
94 static void
extract_devices_dir_from_exec_prefix(char ** devices_loc)95 extract_devices_dir_from_exec_prefix (char **devices_loc)
96 {
97   const char *temp;
98   char *gcc_exec_prefix = *devices_loc;
99   int len = strlen (gcc_exec_prefix);
100 
101   /* Copied from gcc.c.  */
102   if (len > (int) sizeof ("/lib/gcc/") - 1
103       && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
104     {
105       temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
106       if (IS_DIR_SEPARATOR (*temp)
107 	  && filename_ncmp (temp + 1, "lib", 3) == 0
108 	  && IS_DIR_SEPARATOR (temp[4])
109 	  && filename_ncmp (temp + 5, "gcc", 3) == 0)
110 	{
111 	  len -= sizeof ("/lib/gcc/") - 1;
112 	  /* Keep the '/' from the beginning of /lib/gcc.  */
113 	  gcc_exec_prefix[len + 1] = (char) 0;
114 	  *devices_loc = concat (gcc_exec_prefix, rest_of_devices_path, NULL);
115 	  return;
116 	}
117     }
118 }
119 
120 /* Given the path to the GCC executable, return the path to the installed
121    device data in "$TOOLCHAIN_ROOT/msp430-elf/include/devices".
122    Assumes the GCC executable is in "$TOOLCHAIN_ROOT/<somedir>/".  */
123 static void
extract_devices_dir_from_collect_gcc(char ** devices_loc)124 extract_devices_dir_from_collect_gcc (char **devices_loc)
125 {
126   char *t_devices_loc = *devices_loc;
127   /* Go up a directory to the toolchain root.  */
128   t_devices_loc = msp430_dirname (msp430_dirname (t_devices_loc));
129   t_devices_loc = concat (t_devices_loc, rest_of_devices_path, NULL);
130   *devices_loc = t_devices_loc;
131 }
132 
133 /* The path to the MSP430-GCC support files can be specified with the
134    environment variable "MSP430_GCC_INCLUDE_DIR", or installed into the
135    toolchain in the msp430-elf/include/devices subdirectory.
136    We use the GCC_EXEC_PREFIX or COLLECT_GCC environment variables as a starting
137    point for the location of the toolchain, and work out the path to the
138    installed device data from there.
139    Return 0 and set LOCAL_DEVICES_CSV_LOC if we find devices.csv.  Return 1
140    if devices.csv wasn't found.  */
141 int
msp430_check_env_var_for_devices(char ** local_devices_csv_loc)142 msp430_check_env_var_for_devices (char **local_devices_csv_loc)
143 {
144   const int num_vars = 3;
145   const char dirsep[2] = { DIR_SEPARATOR, 0 };
146   /* Both GCC_EXEC_PREFIX and COLLECT_GCC should always be set to the format we
147      expect, as they are required for correct operation of the toolchain.
148      So if they are wrong the user will probably have bigger problems.
149      GCC_EXEC_PREFIX is only defined in the driver, whilst COLLECT_GCC is only
150      defined in the compiler proper, so we need both.  */
151   const char *env_vars[num_vars] = {
152       "MSP430_GCC_INCLUDE_DIR", "GCC_EXEC_PREFIX", "COLLECT_GCC" };
153   enum msp430_include_vars {
154       MSP430_GCC_INCLUDE_DIR,
155       GCC_EXEC_PREFIX,
156       COLLECT_GCC
157   };
158   FILE *devices_csv_file = NULL;
159   int i;
160 
161   for (i = MSP430_GCC_INCLUDE_DIR; i <= COLLECT_GCC; i++)
162     {
163       char *t_devices_loc;
164       char *val = getenv (env_vars[i]);
165       if (val == NULL)
166 	continue;
167       t_devices_loc = xstrdup (val);
168 
169       if (i == MSP430_GCC_INCLUDE_DIR)
170 	{
171 	  if (!IS_DIR_SEPARATOR (t_devices_loc[strlen (t_devices_loc) - 1]))
172 	    t_devices_loc = concat (t_devices_loc, dirsep, NULL);
173 	}
174       else if (i == GCC_EXEC_PREFIX)
175 	extract_devices_dir_from_exec_prefix (&t_devices_loc);
176       else if (i == COLLECT_GCC)
177 	extract_devices_dir_from_collect_gcc (&t_devices_loc);
178 
179       t_devices_loc = concat (t_devices_loc, "devices.csv", NULL);
180       devices_csv_file = fopen (t_devices_loc,  "r");
181       if (devices_csv_file != NULL)
182 	{
183 	  fclose (devices_csv_file);
184 	  *local_devices_csv_loc = t_devices_loc;
185 	  canonicalize_path_dirsep (local_devices_csv_loc);
186 	  return 0;
187 	}
188     }
189   return 1;
190 }
191 
192 /* Spec function which searches the paths passed to the -I and -L options for
193    the "devices.csv" file.  If it is found then the -mdevices-csv-loc option is
194    placed on the command line so the compiler knows the location of the
195    file.  */
196 const char *
msp430_check_path_for_devices(int argc,const char ** argv)197 msp430_check_path_for_devices (int argc, const char **argv)
198 {
199   const char dirsep[2] = { DIR_SEPARATOR, 0 };
200   FILE * devices_file = NULL;
201   char * local_devices_csv_loc = NULL;
202   int i;
203   /* msp430_devices_csv_loc is set by -mdevices-csv-loc, derived_devices_csv_loc
204      is set by this function only.  */
205   if (msp430_devices_csv_loc || derived_devices_csv_loc)
206     return NULL;
207   for (i = 0; i < argc; i++)
208     {
209       char *inc_path = xstrdup (argv[i]);
210       canonicalize_path_dirsep (&inc_path);
211       if (!IS_DIR_SEPARATOR (inc_path[strlen (inc_path) - 1]))
212 	inc_path = concat (inc_path, dirsep, NULL);
213       local_devices_csv_loc = concat (inc_path, "devices.csv", NULL);
214       devices_file = fopen (local_devices_csv_loc, "r");
215       if (devices_file != NULL)
216 	{
217 	  fclose (devices_file);
218 	  derived_devices_csv_loc = local_devices_csv_loc;
219 	  return concat ("-mdevices-csv-loc=", local_devices_csv_loc, NULL);
220 	}
221     }
222   return NULL;
223 }
224 
225 /* Search the devices.csv file for the given MCU name, and load the device
226    data into extracted_mcu_data.
227    Return 1 if MCU wasn't found in devices.csv, or the data couldn't be loaded
228    into extracted_mcu_data.
229    devices.csv has a specific format.  There is a row for column headings which
230    begins with "# Device Name".  The column numbers for CPU_TYPE (MSP430 ISA)
231    and MPY_TYPE (hwmult support) are extracted from this row and used later to
232    extract the ISA and hwmult supported for the given device.
233    The rows containing the MCU data are expected to begin immediately after the
234    column headings.  */
235 static int
parse_devices_csv_1(const char * real_devices_csv_loc,const char * mcu_name)236 parse_devices_csv_1 (const char * real_devices_csv_loc, const char * mcu_name)
237 {
238   FILE * devices_file = fopen (real_devices_csv_loc, "r");
239   /* Some devices have a large number of errata, which means that MPY_TYPE
240      isn't found until the ~100th character in the line.  line_buf_size is set
241      to 200 to account for further possible additions to errata.  */
242   const size_t line_buf_size = 200;
243   char line[line_buf_size];
244   char * res;
245   bool found_headings = false;
246   bool found_mcu = false;
247   int cpu_type = -1;
248   int mpy_type = -1;
249   int cpu_type_column = -1;
250   int mpy_type_column = -1;
251   const char * device_name_heading = "# Device Name";
252   const char * cpu_type_heading = "CPU_TYPE";
253   const char * mpy_type_heading = "MPY_TYPE";
254   /* devices_file should never be NULL at this stage.  */
255   if (devices_file == NULL)
256     {
257       if (msp430_warn_devices_csv)
258 	warning (0, "unexpected error opening %<devices.csv%>");
259       return 1;
260     }
261   while (1)
262     {
263       res = fgets (line, line_buf_size, devices_file);
264       if (res == NULL)
265 	{
266 	  /* The device has not been found in devices.csv.  Don't warn now in
267 	     case it is in the hard-coded data.  We will warn later if the
268 	     device was not found in the hard-coded data either.  */
269 	  goto end;
270 	}
271       else if (!found_headings
272 	       && strncmp (line, device_name_heading,
273 			   strlen (device_name_heading)) == 0)
274 	{
275 	  int curr_column = 0;
276 	  char * heading = strtok (line, ",");
277 	  found_headings = true;
278 	  /* Find which column MPY_TYPE and CPU_TYPE are in.  */
279 	  while (heading != NULL)
280 	    {
281 	      if (strncmp (heading, cpu_type_heading,
282 			   strlen (cpu_type_heading)) == 0)
283 		cpu_type_column = curr_column;
284 	      else if (strncmp (heading, mpy_type_heading,
285 				strlen (mpy_type_heading)) == 0)
286 		mpy_type_column = curr_column;
287 	      if (cpu_type_column != -1 && mpy_type_column != -1)
288 		break;
289 	      heading = strtok (NULL, ",");
290 	      curr_column++;
291 	    }
292 	  if (cpu_type_column == -1 || mpy_type_column == -1)
293 	    {
294 	      if (msp430_warn_devices_csv)
295 		{
296 		  if (cpu_type_column == -1 && mpy_type_column != -1)
297 		    warning (0, "%<CPU_TYPE%> column heading is missing from "
298 			     "%<devices.csv%>");
299 		  else if (mpy_type_column == -1 && cpu_type_column != -1)
300 		    warning (0, "%<MPY_TYPE%> column heading is missing from "
301 			     "%<devices.csv%>");
302 		  else
303 		    warning (0, "%<CPU_TYPE%> and %<MPY_TYPE%> column headings "
304 			     "are missing from %<devices.csv%>");
305 		}
306 	      goto end;
307 	    }
308 	}
309       else if (strncasecmp (line, mcu_name, strlen (mcu_name)) == 0
310 	       && *(line + strlen (mcu_name)) == ',')
311 	{
312 	  if (!found_headings)
313 	    {
314 	      if (msp430_warn_devices_csv)
315 		warning (0, "format of column headings in %<devices.csv%> "
316 			 "is incorrect");
317 	      goto end;
318 	    }
319 	  char * val = strtok (line, ",");
320 	  int final_col_num = ((mpy_type_column > cpu_type_column)
321 			       ? mpy_type_column : cpu_type_column);
322 	  int curr_col;
323 	  bool found_cpu = false;
324 	  bool found_mpy = false;
325 	  for (curr_col = 0; curr_col <= final_col_num; curr_col++)
326 	    {
327 	      /* Strip any new line characters from the last token.  */
328 	      if (curr_col == final_col_num && strlen (val) > 1
329 		  /* ASCII digit 10 == LF, 13 == CR.  */
330 		  && (val[1] == 10 || val[1] == 13))
331 		{
332 		  /* Terminate the string after the first character.  */
333 		  val[1] = 0;
334 		}
335 	      if (curr_col == cpu_type_column)
336 		{
337 		  cpu_type = atoi (val);
338 		  /* Only a single '0', '1' or '2' is accepted.  */
339 		  if (strlen (val) != 1
340 		      /* atoi will return 0 if the string passed as an argument
341 			 is empty or contains only whitespace characters, so we
342 			 must error if 0 is returned but the first character in
343 			 the original string is not '0'.  */
344 		      || (cpu_type == 0 && val[0] != '0')
345 		      || cpu_type > 2 || cpu_type < 0)
346 		    {
347 		      if (msp430_warn_devices_csv)
348 			warning (0, "invalid %<CPU_TYPE%> value of %qs read "
349 				 "from %<devices.csv%> for %qs", val, mcu_name);
350 		      goto end;
351 		    }
352 		  extracted_mcu_data.revision = cpu_type;
353 		  found_cpu = true;
354 		}
355 	      else if (curr_col == mpy_type_column)
356 		{
357 		  mpy_type = atoi (val);
358 		  /* Only a single '0', '1', '2', '4' or '8' is accepted.  */
359 		  if (strlen (val) != 1
360 		      || (mpy_type == 0 && val[0] != '0')
361 		      || !(mpy_type == 0
362 			   || mpy_type == 1
363 			   || mpy_type == 2
364 			   || mpy_type == 4
365 			   || mpy_type == 8))
366 		    {
367 		      if (msp430_warn_devices_csv)
368 			warning (0, "invalid %<MPY_TYPE%> value of %qs read "
369 				 "from %<devices.csv%> for %qs", val, mcu_name);
370 		      goto end;
371 		    }
372 		  extracted_mcu_data.hwmpy = mpy_type;
373 		  found_mpy = true;
374 		}
375 	      if (found_cpu && found_mpy)
376 		{
377 		  extracted_mcu_data.name = mcu_name;
378 		  found_mcu = true;
379 		  goto end;
380 		}
381 	      val = strtok (NULL, ",");
382 	    }
383 	  if (msp430_warn_devices_csv && (cpu_type == -1 || mpy_type == -1))
384 	    warning (0, "unknown error reading %s from "
385 		     "%<devices.csv%>",
386 		     (cpu_type != -1 ? "%<MPY_TYPE%>"
387 		      : (mpy_type != -1 ? "%<CPU_TYPE%>"
388 			 : "%<CPU_TYPE%> and %<MPY_TYPE%>")));
389 	  goto end;
390 	}
391     }
392 end:
393   fclose (devices_file);
394   if (!found_mcu)
395     return 1;
396   return 0;
397 }
398 
399 /* Wrapper for the parse_devices_csv_1 work function.
400    A return code of 0 indicates that the MCU data has been successfully
401    extracted into extracted_mcu_data.
402    A return code of 1 indicates that the specified MCU wasn't found in
403    devices.csv.
404    A return code of 2 indicates that devices.csv wasn't found at all.  */
405 static int
parse_devices_csv(const char * mcu_name)406 parse_devices_csv (const char * mcu_name)
407 {
408   /* First check if the path to devices.csv was set by -mdevices-csv-loc.  */
409   if (msp430_devices_csv_loc != NULL)
410     return parse_devices_csv_1 (msp430_devices_csv_loc, mcu_name);
411   /* Otherwise check if the path to devices.csv was found another way.  */
412   else if (derived_devices_csv_loc != NULL)
413     return parse_devices_csv_1 (derived_devices_csv_loc, mcu_name);
414   /* Otherwise we need to use environment variables to try and find it.  */
415   if (msp430_check_env_var_for_devices (&derived_devices_csv_loc))
416     /* devices.csv was not found.  */
417     return 2;
418   return parse_devices_csv_1 (derived_devices_csv_loc, mcu_name);
419 }
420 
421 /* Main entry point to load the MCU data for the given -mmcu into
422    extracted_mcu_data.
423    First, the "devices.csv" MCU data file is searched for, if it is found, and
424    the MCU has a record in it, then that data is used.
425    Otherwise, hard_msp430_mcu_data (initialized at the bottom of this
426    file) is searched for the MCU name.
427    This function only needs to be executed once, but it can be first called
428    from a number of different locations.  */
429 void
msp430_extract_mcu_data(const char * mcu_name)430 msp430_extract_mcu_data (const char * mcu_name)
431 {
432   static int executed = 0;
433   int devices_csv_not_found = 0;
434   int i;
435   if (mcu_name == NULL || executed == 1)
436     return;
437   executed = 1;
438   /* If parse_devices_csv returns non-zero we need to use the
439      hard-coded data.  */
440   switch (parse_devices_csv (mcu_name))
441     {
442     case 0:
443       return;
444     case 1:
445       /* MCU not found in devices.csv.  Warn later if it's not in the
446 	 hard-coded data either.  */
447       break;
448     case 2:
449       devices_csv_not_found = 1;
450       break;
451     default:
452       gcc_unreachable ();
453     }
454   for (i = ARRAY_SIZE (hard_msp430_mcu_data); i--;)
455     if (strcasecmp (mcu_name, hard_msp430_mcu_data[i].name) == 0)
456       {
457 	extracted_mcu_data = hard_msp430_mcu_data[i];
458 	break;
459       }
460   /* Validation checks.  */
461   if (extracted_mcu_data.name != NULL)
462     {
463       switch (extracted_mcu_data.hwmpy)
464 	{
465 	case 0:
466 	case 1:
467 	case 2:
468 	case 4:
469 	case 8: break;
470 	default:
471 	  error ("unrecognized %<hwmpy%> field in "
472 		 "%<hard_msp430_mcu_data[%d]%>: %qd", i,
473 		 hard_msp430_mcu_data[i].hwmpy);
474 	  break;
475 	}
476       switch (extracted_mcu_data.revision)
477 	{
478 	case 0:
479 	case 1:
480 	case 2: break;
481 	default:
482 	  error ("unrecognized %<revision%> field in "
483 		 "%<hard_msp430_mcu_data[%d]%>: %qd", i,
484 		 hard_msp430_mcu_data[i].revision);
485 	}
486     }
487   else if (msp430_warn_devices_csv && devices_csv_not_found)
488     warning (0, "could not locate MCU data file %<devices.csv%>");
489   else if (msp430_warn_mcu && extracted_mcu_data.name == NULL)
490     {
491       /* FIXME: We should warn here that the MCU name is unrecognized, but
492 	 msp430_option_override will warn about an unrecognized MCU as well.
493 	 The benefit of warning here is that this is code common to both the
494 	 driver and compiler proper, so a warning will be emitted when
495 	 assembling/linking via the driver, whilst msp430_option_override will
496 	 only be called when preprocessing or compiling.  */
497     }
498 }
499 
500 /* The data in this structure has been extracted from version 1.194 of the
501    devices.csv file released by TI in September 2016.  */
502 
503 struct t_msp430_mcu_data hard_msp430_mcu_data[605] =
504   {
505     { "cc430f5123",2,8 },
506     { "cc430f5125",2,8 },
507     { "cc430f5133",2,8 },
508     { "cc430f5135",2,8 },
509     { "cc430f5137",2,8 },
510     { "cc430f5143",2,8 },
511     { "cc430f5145",2,8 },
512     { "cc430f5147",2,8 },
513     { "cc430f6125",2,8 },
514     { "cc430f6126",2,8 },
515     { "cc430f6127",2,8 },
516     { "cc430f6135",2,8 },
517     { "cc430f6137",2,8 },
518     { "cc430f6143",2,8 },
519     { "cc430f6145",2,8 },
520     { "cc430f6147",2,8 },
521     { "msp430afe221",0,2 },
522     { "msp430afe222",0,2 },
523     { "msp430afe223",0,2 },
524     { "msp430afe231",0,2 },
525     { "msp430afe232",0,2 },
526     { "msp430afe233",0,2 },
527     { "msp430afe251",0,2 },
528     { "msp430afe252",0,2 },
529     { "msp430afe253",0,2 },
530     { "msp430bt5190",2,8 },
531     { "msp430c091",0,0 },
532     { "msp430c092",0,0 },
533     { "msp430c111",0,0 },
534     { "msp430c1111",0,0 },
535     { "msp430c112",0,0 },
536     { "msp430c1121",0,0 },
537     { "msp430c1331",0,0 },
538     { "msp430c1351",0,0 },
539     { "msp430c311s",0,0 },
540     { "msp430c312",0,0 },
541     { "msp430c313",0,0 },
542     { "msp430c314",0,0 },
543     { "msp430c315",0,0 },
544     { "msp430c323",0,0 },
545     { "msp430c325",0,0 },
546     { "msp430c336",0,1 },
547     { "msp430c337",0,1 },
548     { "msp430c412",0,0 },
549     { "msp430c413",0,0 },
550     { "msp430cg4616",1,1 },
551     { "msp430cg4617",1,1 },
552     { "msp430cg4618",1,1 },
553     { "msp430cg4619",1,1 },
554     { "msp430e112",0,0 },
555     { "msp430e313",0,0 },
556     { "msp430e315",0,0 },
557     { "msp430e325",0,0 },
558     { "msp430e337",0,1 },
559     { "msp430f110",0,0 },
560     { "msp430f1101",0,0 },
561     { "msp430f1101a",0,0 },
562     { "msp430f1111",0,0 },
563     { "msp430f1111a",0,0 },
564     { "msp430f112",0,0 },
565     { "msp430f1121",0,0 },
566     { "msp430f1121a",0,0 },
567     { "msp430f1122",0,0 },
568     { "msp430f1132",0,0 },
569     { "msp430f122",0,0 },
570     { "msp430f1222",0,0 },
571     { "msp430f123",0,0 },
572     { "msp430f1232",0,0 },
573     { "msp430f133",0,0 },
574     { "msp430f135",0,0 },
575     { "msp430f147",0,1 },
576     { "msp430f1471",0,1 },
577     { "msp430f148",0,1 },
578     { "msp430f1481",0,1 },
579     { "msp430f149",0,1 },
580     { "msp430f1491",0,1 },
581     { "msp430f155",0,0 },
582     { "msp430f156",0,0 },
583     { "msp430f157",0,0 },
584     { "msp430f1610",0,1 },
585     { "msp430f1611",0,1 },
586     { "msp430f1612",0,1 },
587     { "msp430f167",0,1 },
588     { "msp430f168",0,1 },
589     { "msp430f169",0,1 },
590     { "msp430f2001",0,0 },
591     { "msp430f2002",0,0 },
592     { "msp430f2003",0,0 },
593     { "msp430f2011",0,0 },
594     { "msp430f2012",0,0 },
595     { "msp430f2013",0,0 },
596     { "msp430f2101",0,0 },
597     { "msp430f2111",0,0 },
598     { "msp430f2112",0,0 },
599     { "msp430f2121",0,0 },
600     { "msp430f2122",0,0 },
601     { "msp430f2131",0,0 },
602     { "msp430f2132",0,0 },
603     { "msp430f2232",0,0 },
604     { "msp430f2234",0,0 },
605     { "msp430f2252",0,0 },
606     { "msp430f2254",0,0 },
607     { "msp430f2272",0,0 },
608     { "msp430f2274",0,0 },
609     { "msp430f233",0,2 },
610     { "msp430f2330",0,2 },
611     { "msp430f235",0,2 },
612     { "msp430f2350",0,2 },
613     { "msp430f2370",0,2 },
614     { "msp430f2410",0,2 },
615     { "msp430f2416",1,2 },
616     { "msp430f2417",1,2 },
617     { "msp430f2418",1,2 },
618     { "msp430f2419",1,2 },
619     { "msp430f247",0,2 },
620     { "msp430f2471",0,2 },
621     { "msp430f248",0,2 },
622     { "msp430f2481",0,2 },
623     { "msp430f249",0,2 },
624     { "msp430f2491",0,2 },
625     { "msp430f2616",1,2 },
626     { "msp430f2617",1,2 },
627     { "msp430f2618",1,2 },
628     { "msp430f2619",1,2 },
629     { "msp430f412",0,0 },
630     { "msp430f413",0,0 },
631     { "msp430f4132",0,0 },
632     { "msp430f415",0,0 },
633     { "msp430f4152",0,0 },
634     { "msp430f417",0,0 },
635     { "msp430f423",0,1 },
636     { "msp430f423a",0,1 },
637     { "msp430f425",0,1 },
638     { "msp430f4250",0,0 },
639     { "msp430f425a",0,1 },
640     { "msp430f4260",0,0 },
641     { "msp430f427",0,1 },
642     { "msp430f4270",0,0 },
643     { "msp430f427a",0,1 },
644     { "msp430f435",0,0 },
645     { "msp430f4351",0,0 },
646     { "msp430f436",0,0 },
647     { "msp430f4361",0,0 },
648     { "msp430f437",0,0 },
649     { "msp430f4371",0,0 },
650     { "msp430f438",0,0 },
651     { "msp430f439",0,0 },
652     { "msp430f447",0,1 },
653     { "msp430f448",0,1 },
654     { "msp430f4481",0,1 },
655     { "msp430f449",0,1 },
656     { "msp430f4491",0,1 },
657     { "msp430f4616",1,1 },
658     { "msp430f46161",1,1 },
659     { "msp430f4617",1,1 },
660     { "msp430f46171",1,1 },
661     { "msp430f4618",1,1 },
662     { "msp430f46181",1,1 },
663     { "msp430f4619",1,1 },
664     { "msp430f46191",1,1 },
665     { "msp430f47126",1,4 },
666     { "msp430f47127",1,4 },
667     { "msp430f47163",1,4 },
668     { "msp430f47166",1,4 },
669     { "msp430f47167",1,4 },
670     { "msp430f47173",1,4 },
671     { "msp430f47176",1,4 },
672     { "msp430f47177",1,4 },
673     { "msp430f47183",1,4 },
674     { "msp430f47186",1,4 },
675     { "msp430f47187",1,4 },
676     { "msp430f47193",1,4 },
677     { "msp430f47196",1,4 },
678     { "msp430f47197",1,4 },
679     { "msp430f477",0,0 },
680     { "msp430f478",0,0 },
681     { "msp430f4783",0,4 },
682     { "msp430f4784",0,4 },
683     { "msp430f479",0,0 },
684     { "msp430f4793",0,4 },
685     { "msp430f4794",0,4 },
686     { "msp430f5131",2,8 },
687     { "msp430f5132",2,8 },
688     { "msp430f5151",2,8 },
689     { "msp430f5152",2,8 },
690     { "msp430f5171",2,8 },
691     { "msp430f5172",2,8 },
692     { "msp430f5212",2,8 },
693     { "msp430f5213",2,8 },
694     { "msp430f5214",2,8 },
695     { "msp430f5217",2,8 },
696     { "msp430f5218",2,8 },
697     { "msp430f5219",2,8 },
698     { "msp430f5222",2,8 },
699     { "msp430f5223",2,8 },
700     { "msp430f5224",2,8 },
701     { "msp430f5227",2,8 },
702     { "msp430f5228",2,8 },
703     { "msp430f5229",2,8 },
704     { "msp430f5232",2,8 },
705     { "msp430f5234",2,8 },
706     { "msp430f5237",2,8 },
707     { "msp430f5239",2,8 },
708     { "msp430f5242",2,8 },
709     { "msp430f5244",2,8 },
710     { "msp430f5247",2,8 },
711     { "msp430f5249",2,8 },
712     { "msp430f5252",2,8 },
713     { "msp430f5253",2,8 },
714     { "msp430f5254",2,8 },
715     { "msp430f5255",2,8 },
716     { "msp430f5256",2,8 },
717     { "msp430f5257",2,8 },
718     { "msp430f5258",2,8 },
719     { "msp430f5259",2,8 },
720     { "msp430f5304",2,8 },
721     { "msp430f5308",2,8 },
722     { "msp430f5309",2,8 },
723     { "msp430f5310",2,8 },
724     { "msp430f5324",2,8 },
725     { "msp430f5325",2,8 },
726     { "msp430f5326",2,8 },
727     { "msp430f5327",2,8 },
728     { "msp430f5328",2,8 },
729     { "msp430f5329",2,8 },
730     { "msp430f5333",2,8 },
731     { "msp430f5335",2,8 },
732     { "msp430f5336",2,8 },
733     { "msp430f5338",2,8 },
734     { "msp430f5340",2,8 },
735     { "msp430f5341",2,8 },
736     { "msp430f5342",2,8 },
737     { "msp430f5358",2,8 },
738     { "msp430f5359",2,8 },
739     { "msp430f5418",2,8 },
740     { "msp430f5418a",2,8 },
741     { "msp430f5419",2,8 },
742     { "msp430f5419a",2,8 },
743     { "msp430f5435",2,8 },
744     { "msp430f5435a",2,8 },
745     { "msp430f5436",2,8 },
746     { "msp430f5436a",2,8 },
747     { "msp430f5437",2,8 },
748     { "msp430f5437a",2,8 },
749     { "msp430f5438",2,8 },
750     { "msp430f5438a",2,8 },
751     { "msp430f5500",2,8 },
752     { "msp430f5501",2,8 },
753     { "msp430f5502",2,8 },
754     { "msp430f5503",2,8 },
755     { "msp430f5504",2,8 },
756     { "msp430f5505",2,8 },
757     { "msp430f5506",2,8 },
758     { "msp430f5507",2,8 },
759     { "msp430f5508",2,8 },
760     { "msp430f5509",2,8 },
761     { "msp430f5510",2,8 },
762     { "msp430f5513",2,8 },
763     { "msp430f5514",2,8 },
764     { "msp430f5515",2,8 },
765     { "msp430f5517",2,8 },
766     { "msp430f5519",2,8 },
767     { "msp430f5521",2,8 },
768     { "msp430f5522",2,8 },
769     { "msp430f5524",2,8 },
770     { "msp430f5525",2,8 },
771     { "msp430f5526",2,8 },
772     { "msp430f5527",2,8 },
773     { "msp430f5528",2,8 },
774     { "msp430f5529",2,8 },
775     { "msp430f5630",2,8 },
776     { "msp430f5631",2,8 },
777     { "msp430f5632",2,8 },
778     { "msp430f5633",2,8 },
779     { "msp430f5634",2,8 },
780     { "msp430f5635",2,8 },
781     { "msp430f5636",2,8 },
782     { "msp430f5637",2,8 },
783     { "msp430f5638",2,8 },
784     { "msp430f5658",2,8 },
785     { "msp430f5659",2,8 },
786     { "msp430f5xx_6xxgeneric",2,8 },
787     { "msp430f6433",2,8 },
788     { "msp430f6435",2,8 },
789     { "msp430f6436",2,8 },
790     { "msp430f6438",2,8 },
791     { "msp430f6458",2,8 },
792     { "msp430f6459",2,8 },
793     { "msp430f6630",2,8 },
794     { "msp430f6631",2,8 },
795     { "msp430f6632",2,8 },
796     { "msp430f6633",2,8 },
797     { "msp430f6634",2,8 },
798     { "msp430f6635",2,8 },
799     { "msp430f6636",2,8 },
800     { "msp430f6637",2,8 },
801     { "msp430f6638",2,8 },
802     { "msp430f6658",2,8 },
803     { "msp430f6659",2,8 },
804     { "msp430f6720",2,8 },
805     { "msp430f6720a",2,8 },
806     { "msp430f6721",2,8 },
807     { "msp430f6721a",2,8 },
808     { "msp430f6723",2,8 },
809     { "msp430f6723a",2,8 },
810     { "msp430f6724",2,8 },
811     { "msp430f6724a",2,8 },
812     { "msp430f6725",2,8 },
813     { "msp430f6725a",2,8 },
814     { "msp430f6726",2,8 },
815     { "msp430f6726a",2,8 },
816     { "msp430f6730",2,8 },
817     { "msp430f6730a",2,8 },
818     { "msp430f6731",2,8 },
819     { "msp430f6731a",2,8 },
820     { "msp430f6733",2,8 },
821     { "msp430f6733a",2,8 },
822     { "msp430f6734",2,8 },
823     { "msp430f6734a",2,8 },
824     { "msp430f6735",2,8 },
825     { "msp430f6735a",2,8 },
826     { "msp430f6736",2,8 },
827     { "msp430f6736a",2,8 },
828     { "msp430f6745",2,8 },
829     { "msp430f67451",2,8 },
830     { "msp430f67451a",2,8 },
831     { "msp430f6745a",2,8 },
832     { "msp430f6746",2,8 },
833     { "msp430f67461",2,8 },
834     { "msp430f67461a",2,8 },
835     { "msp430f6746a",2,8 },
836     { "msp430f6747",2,8 },
837     { "msp430f67471",2,8 },
838     { "msp430f67471a",2,8 },
839     { "msp430f6747a",2,8 },
840     { "msp430f6748",2,8 },
841     { "msp430f67481",2,8 },
842     { "msp430f67481a",2,8 },
843     { "msp430f6748a",2,8 },
844     { "msp430f6749",2,8 },
845     { "msp430f67491",2,8 },
846     { "msp430f67491a",2,8 },
847     { "msp430f6749a",2,8 },
848     { "msp430f67621",2,8 },
849     { "msp430f67621a",2,8 },
850     { "msp430f67641",2,8 },
851     { "msp430f67641a",2,8 },
852     { "msp430f6765",2,8 },
853     { "msp430f67651",2,8 },
854     { "msp430f67651a",2,8 },
855     { "msp430f6765a",2,8 },
856     { "msp430f6766",2,8 },
857     { "msp430f67661",2,8 },
858     { "msp430f67661a",2,8 },
859     { "msp430f6766a",2,8 },
860     { "msp430f6767",2,8 },
861     { "msp430f67671",2,8 },
862     { "msp430f67671a",2,8 },
863     { "msp430f6767a",2,8 },
864     { "msp430f6768",2,8 },
865     { "msp430f67681",2,8 },
866     { "msp430f67681a",2,8 },
867     { "msp430f6768a",2,8 },
868     { "msp430f6769",2,8 },
869     { "msp430f67691",2,8 },
870     { "msp430f67691a",2,8 },
871     { "msp430f6769a",2,8 },
872     { "msp430f6775",2,8 },
873     { "msp430f67751",2,8 },
874     { "msp430f67751a",2,8 },
875     { "msp430f6775a",2,8 },
876     { "msp430f6776",2,8 },
877     { "msp430f67761",2,8 },
878     { "msp430f67761a",2,8 },
879     { "msp430f6776a",2,8 },
880     { "msp430f6777",2,8 },
881     { "msp430f67771",2,8 },
882     { "msp430f67771a",2,8 },
883     { "msp430f6777a",2,8 },
884     { "msp430f6778",2,8 },
885     { "msp430f67781",2,8 },
886     { "msp430f67781a",2,8 },
887     { "msp430f6778a",2,8 },
888     { "msp430f6779",2,8 },
889     { "msp430f67791",2,8 },
890     { "msp430f67791a",2,8 },
891     { "msp430f6779a",2,8 },
892     { "msp430fe423",0,0 },
893     { "msp430fe4232",0,0 },
894     { "msp430fe423a",0,0 },
895     { "msp430fe4242",0,0 },
896     { "msp430fe425",0,0 },
897     { "msp430fe4252",0,0 },
898     { "msp430fe425a",0,0 },
899     { "msp430fe427",0,0 },
900     { "msp430fe4272",0,0 },
901     { "msp430fe427a",0,0 },
902     { "msp430fg4250",0,0 },
903     { "msp430fg4260",0,0 },
904     { "msp430fg4270",0,0 },
905     { "msp430fg437",0,0 },
906     { "msp430fg438",0,0 },
907     { "msp430fg439",0,0 },
908     { "msp430fg4616",1,1 },
909     { "msp430fg4617",1,1 },
910     { "msp430fg4618",1,1 },
911     { "msp430fg4619",1,1 },
912     { "msp430fg477",0,0 },
913     { "msp430fg478",0,0 },
914     { "msp430fg479",0,0 },
915     { "msp430fg6425",2,8 },
916     { "msp430fg6426",2,8 },
917     { "msp430fg6625",2,8 },
918     { "msp430fg6626",2,8 },
919     { "msp430fr2032",2,0 },
920     { "msp430fr2033",2,0 },
921     { "msp430fr2110",2,0 },
922     { "msp430fr2111",2,0 },
923     { "msp430fr2310",2,0 },
924     { "msp430fr2311",2,0 },
925     { "msp430fr2433",2,8 },
926     { "msp430fr2532",2,8 },
927     { "msp430fr2533",2,8 },
928     { "msp430fr2632",2,8 },
929     { "msp430fr2633",2,8 },
930     { "msp430fr2xx_4xxgeneric",2,8 },
931     { "msp430fr4131",2,0 },
932     { "msp430fr4132",2,0 },
933     { "msp430fr4133",2,0 },
934     { "msp430fr5720",2,8 },
935     { "msp430fr5721",2,8 },
936     { "msp430fr5722",2,8 },
937     { "msp430fr5723",2,8 },
938     { "msp430fr5724",2,8 },
939     { "msp430fr5725",2,8 },
940     { "msp430fr5726",2,8 },
941     { "msp430fr5727",2,8 },
942     { "msp430fr5728",2,8 },
943     { "msp430fr5729",2,8 },
944     { "msp430fr5730",2,8 },
945     { "msp430fr5731",2,8 },
946     { "msp430fr5732",2,8 },
947     { "msp430fr5733",2,8 },
948     { "msp430fr5734",2,8 },
949     { "msp430fr5735",2,8 },
950     { "msp430fr5736",2,8 },
951     { "msp430fr5737",2,8 },
952     { "msp430fr5738",2,8 },
953     { "msp430fr5739",2,8 },
954     { "msp430fr57xxgeneric",2,8 },
955     { "msp430fr5847",2,8 },
956     { "msp430fr58471",2,8 },
957     { "msp430fr5848",2,8 },
958     { "msp430fr5849",2,8 },
959     { "msp430fr5857",2,8 },
960     { "msp430fr5858",2,8 },
961     { "msp430fr5859",2,8 },
962     { "msp430fr5867",2,8 },
963     { "msp430fr58671",2,8 },
964     { "msp430fr5868",2,8 },
965     { "msp430fr5869",2,8 },
966     { "msp430fr5870",2,8 },
967     { "msp430fr5872",2,8 },
968     { "msp430fr58721",2,8 },
969     { "msp430fr5887",2,8 },
970     { "msp430fr5888",2,8 },
971     { "msp430fr5889",2,8 },
972     { "msp430fr58891",2,8 },
973     { "msp430fr5922",2,8 },
974     { "msp430fr59221",2,8 },
975     { "msp430fr5947",2,8 },
976     { "msp430fr59471",2,8 },
977     { "msp430fr5948",2,8 },
978     { "msp430fr5949",2,8 },
979     { "msp430fr5957",2,8 },
980     { "msp430fr5958",2,8 },
981     { "msp430fr5959",2,8 },
982     { "msp430fr5962",2,8 },
983     { "msp430fr5964",2,8 },
984     { "msp430fr5967",2,8 },
985     { "msp430fr5968",2,8 },
986     { "msp430fr5969",2,8 },
987     { "msp430fr59691",2,8 },
988     { "msp430fr5970",2,8 },
989     { "msp430fr5972",2,8 },
990     { "msp430fr59721",2,8 },
991     { "msp430fr5986",2,8 },
992     { "msp430fr5987",2,8 },
993     { "msp430fr5988",2,8 },
994     { "msp430fr5989",2,8 },
995     { "msp430fr59891",2,8 },
996     { "msp430fr5992",2,8 },
997     { "msp430fr5994",2,8 },
998     { "msp430fr59941",2,8 },
999     { "msp430fr5xx_6xxgeneric",2,8 },
1000     { "msp430fr6820",2,8 },
1001     { "msp430fr6822",2,8 },
1002     { "msp430fr68221",2,8 },
1003     { "msp430fr6870",2,8 },
1004     { "msp430fr6872",2,8 },
1005     { "msp430fr68721",2,8 },
1006     { "msp430fr6877",2,8 },
1007     { "msp430fr6879",2,8 },
1008     { "msp430fr68791",2,8 },
1009     { "msp430fr6887",2,8 },
1010     { "msp430fr6888",2,8 },
1011     { "msp430fr6889",2,8 },
1012     { "msp430fr68891",2,8 },
1013     { "msp430fr6920",2,8 },
1014     { "msp430fr6922",2,8 },
1015     { "msp430fr69221",2,8 },
1016     { "msp430fr6927",2,8 },
1017     { "msp430fr69271",2,8 },
1018     { "msp430fr6928",2,8 },
1019     { "msp430fr6970",2,8 },
1020     { "msp430fr6972",2,8 },
1021     { "msp430fr69721",2,8 },
1022     { "msp430fr6977",2,8 },
1023     { "msp430fr6979",2,8 },
1024     { "msp430fr69791",2,8 },
1025     { "msp430fr6987",2,8 },
1026     { "msp430fr6988",2,8 },
1027     { "msp430fr6989",2,8 },
1028     { "msp430fr69891",2,8 },
1029     { "msp430fw423",0,0 },
1030     { "msp430fw425",0,0 },
1031     { "msp430fw427",0,0 },
1032     { "msp430fw428",0,0 },
1033     { "msp430fw429",0,0 },
1034     { "msp430g2001",0,0 },
1035     { "msp430g2101",0,0 },
1036     { "msp430g2102",0,0 },
1037     { "msp430g2111",0,0 },
1038     { "msp430g2112",0,0 },
1039     { "msp430g2113",0,0 },
1040     { "msp430g2121",0,0 },
1041     { "msp430g2131",0,0 },
1042     { "msp430g2132",0,0 },
1043     { "msp430g2152",0,0 },
1044     { "msp430g2153",0,0 },
1045     { "msp430g2201",0,0 },
1046     { "msp430g2202",0,0 },
1047     { "msp430g2203",0,0 },
1048     { "msp430g2210",0,0 },
1049     { "msp430g2211",0,0 },
1050     { "msp430g2212",0,0 },
1051     { "msp430g2213",0,0 },
1052     { "msp430g2221",0,0 },
1053     { "msp430g2230",0,0 },
1054     { "msp430g2231",0,0 },
1055     { "msp430g2232",0,0 },
1056     { "msp430g2233",0,0 },
1057     { "msp430g2252",0,0 },
1058     { "msp430g2253",0,0 },
1059     { "msp430g2302",0,0 },
1060     { "msp430g2303",0,0 },
1061     { "msp430g2312",0,0 },
1062     { "msp430g2313",0,0 },
1063     { "msp430g2332",0,0 },
1064     { "msp430g2333",0,0 },
1065     { "msp430g2352",0,0 },
1066     { "msp430g2353",0,0 },
1067     { "msp430g2402",0,0 },
1068     { "msp430g2403",0,0 },
1069     { "msp430g2412",0,0 },
1070     { "msp430g2413",0,0 },
1071     { "msp430g2432",0,0 },
1072     { "msp430g2433",0,0 },
1073     { "msp430g2444",0,0 },
1074     { "msp430g2452",0,0 },
1075     { "msp430g2453",0,0 },
1076     { "msp430g2513",0,0 },
1077     { "msp430g2533",0,0 },
1078     { "msp430g2544",0,0 },
1079     { "msp430g2553",0,0 },
1080     { "msp430g2744",0,0 },
1081     { "msp430g2755",0,0 },
1082     { "msp430g2855",0,0 },
1083     { "msp430g2955",0,0 },
1084     { "msp430i2020",0,2 },
1085     { "msp430i2021",0,2 },
1086     { "msp430i2030",0,2 },
1087     { "msp430i2031",0,2 },
1088     { "msp430i2040",0,2 },
1089     { "msp430i2041",0,2 },
1090     { "msp430i2xxgeneric",0,2 },
1091     { "msp430l092",0,0 },
1092     { "msp430p112",0,0 },
1093     { "msp430p313",0,0 },
1094     { "msp430p315",0,0 },
1095     { "msp430p315s",0,0 },
1096     { "msp430p325",0,0 },
1097     { "msp430p337",0,1 },
1098     { "msp430sl5438a",2,8 },
1099     { "msp430tch5e",0,0 },
1100     { "msp430xgeneric",2,8 },
1101     { "rf430f5144",2,8 },
1102     { "rf430f5155",2,8 },
1103     { "rf430f5175",2,8 },
1104     { "rf430frl152h",0,0 },
1105     { "rf430frl152h_rom",0,0 },
1106     { "rf430frl153h",0,0 },
1107     { "rf430frl153h_rom",0,0 },
1108     { "rf430frl154h",0,0 },
1109     { "rf430frl154h_rom",0,0 }
1110   };
1111