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
34struct t_msp430_mcu_data extracted_mcu_data;
35/* Initialized at the bottom of this file.  */
36extern 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.  */
40char *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.  */
44static void
45canonicalize_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.  */
58char *
59msp430_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.  */
86static 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.  */
94static void
95extract_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>/".  */
123static void
124extract_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.  */
141int
142msp430_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.  */
196const char *
197msp430_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.  */
235static int
236parse_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    }
392end:
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.  */
405static int
406parse_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.  */
429void
430msp430_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
503struct 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