xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/config/msp430/driver-msp430.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
136ac495dSmrg /* Subroutines for the gcc driver.
2*8feb0f0bSmrg    Copyright (C) 2015-2020 Free Software Foundation, Inc.
336ac495dSmrg    Contributed by Georg-Johann Lay <avr@gjlay.de>
436ac495dSmrg 
536ac495dSmrg    This file is part of GCC.
636ac495dSmrg 
736ac495dSmrg    GCC is free software; you can redistribute it and/or modify
836ac495dSmrg    it under the terms of the GNU General Public License as published by
936ac495dSmrg    the Free Software Foundation; either version 3, or (at your option)
1036ac495dSmrg    any later version.
1136ac495dSmrg 
1236ac495dSmrg    GCC is distributed in the hope that it will be useful,
1336ac495dSmrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
1436ac495dSmrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1536ac495dSmrg    GNU General Public License for more details.
1636ac495dSmrg 
1736ac495dSmrg    You should have received a copy of the GNU General Public License
1836ac495dSmrg    along with GCC; see the file COPYING3.  If not see
1936ac495dSmrg    <http://www.gnu.org/licenses/>.  */
2036ac495dSmrg 
21a2dc1f3fSmrg #define IN_TARGET_CODE 1
22a2dc1f3fSmrg 
2336ac495dSmrg #include "config.h"
2436ac495dSmrg #include "system.h"
2536ac495dSmrg #include "coretypes.h"
2636ac495dSmrg #include "diagnostic.h"
2736ac495dSmrg #include "tm.h"
28*8feb0f0bSmrg #include "msp430-devices.h"
2936ac495dSmrg 
30*8feb0f0bSmrg /* This spec function is called if the user has provided an -mmcu option without
31*8feb0f0bSmrg    an -mcpu option.  It will place the correct -mcpu option for the given -mmcu
32*8feb0f0bSmrg    onto the command line, to ensure the correct ISA multilib is selected.  */
33*8feb0f0bSmrg const char *
msp430_select_cpu(int argc,const char ** argv)34*8feb0f0bSmrg msp430_select_cpu (int argc, const char ** argv)
3536ac495dSmrg {
36*8feb0f0bSmrg   if (argc == 0)
37*8feb0f0bSmrg     {
38*8feb0f0bSmrg       error ("expected an argument to %<msp430_select_cpu%>");
39*8feb0f0bSmrg       return NULL;
4036ac495dSmrg     }
41*8feb0f0bSmrg   msp430_extract_mcu_data (argv[0]);
42*8feb0f0bSmrg   if (extracted_mcu_data.name != NULL)
4336ac495dSmrg     {
44*8feb0f0bSmrg       switch (extracted_mcu_data.revision)
45*8feb0f0bSmrg 	{
46*8feb0f0bSmrg 	case 0: return "-mcpu=msp430";
47*8feb0f0bSmrg 	case 1: return "-mcpu=msp430x";
48*8feb0f0bSmrg 	case 2: return "-mcpu=msp430xv2";
49*8feb0f0bSmrg 	default:
50*8feb0f0bSmrg 	  gcc_unreachable ();
51*8feb0f0bSmrg 	}
52*8feb0f0bSmrg     }
53*8feb0f0bSmrg   /* MCU wasn't found, the compiler proper will warn about this.  */
54*8feb0f0bSmrg   return NULL;
55*8feb0f0bSmrg }
56*8feb0f0bSmrg 
57*8feb0f0bSmrg /* Spec function to set a global variable to a specific value in the driver.
58*8feb0f0bSmrg    The first argument is the variable name, and the second is the value to set
59*8feb0f0bSmrg    it to.
60*8feb0f0bSmrg    Currently only "msp430_warn_devices_csv" and "msp430_devices_csv_loc" are
61*8feb0f0bSmrg    supported.
62*8feb0f0bSmrg    The intention is that we can take a "Target" option and set the variable
63*8feb0f0bSmrg    associated with it in the driver as well.  Whilst the driver sees "Target"
64*8feb0f0bSmrg    options, it does not set the variables associated with that option.  */
65*8feb0f0bSmrg const char *
msp430_set_driver_var(int argc,const char ** argv)66*8feb0f0bSmrg msp430_set_driver_var (int argc, const char ** argv)
67*8feb0f0bSmrg {
68*8feb0f0bSmrg   if (argc != 2)
69*8feb0f0bSmrg     error ("%<msp430_set_driver_var%> expects 2 arguments");
70*8feb0f0bSmrg   else if (strcmp (argv[0], "msp430_warn_devices_csv") == 0)
71*8feb0f0bSmrg     msp430_warn_devices_csv = atoi (argv[1]);
72*8feb0f0bSmrg   else if (strcmp (argv[0], "msp430_devices_csv_loc") == 0)
73*8feb0f0bSmrg     msp430_devices_csv_loc = argv[1];
74*8feb0f0bSmrg   else
75*8feb0f0bSmrg     error ("unhandled arguments %qs and %qs to %<msp430_set_driver_var%>",
76*8feb0f0bSmrg 	   argv[0], argv[1]);
77*8feb0f0bSmrg   return NULL;
78*8feb0f0bSmrg }
7936ac495dSmrg 
8036ac495dSmrg /* Implement spec function `msp430_hwmult_lib´.  */
8136ac495dSmrg 
8236ac495dSmrg const char *
msp430_select_hwmult_lib(int argc ATTRIBUTE_UNUSED,const char ** argv ATTRIBUTE_UNUSED)83*8feb0f0bSmrg msp430_select_hwmult_lib (int argc ATTRIBUTE_UNUSED,
84*8feb0f0bSmrg 			  const char ** argv ATTRIBUTE_UNUSED)
8536ac495dSmrg {
8636ac495dSmrg   int i;
8736ac495dSmrg 
8836ac495dSmrg   switch (argc)
8936ac495dSmrg     {
9036ac495dSmrg     case 1:
9136ac495dSmrg       if (strcasecmp (argv[0], "default"))
9236ac495dSmrg 	error ("unexpected argument to msp430_select_hwmult_lib: %s", argv[0]);
9336ac495dSmrg       break;
9436ac495dSmrg 
9536ac495dSmrg     default:
9636ac495dSmrg       /* We can get three or more arguments passed to this function.
9736ac495dSmrg 	 This happens when the same option is repeated on the command line.
9836ac495dSmrg 	 For example:
9936ac495dSmrg 	 msp430-elf-gcc -mhwmult=none -mhwmult=16bit foo.c
10036ac495dSmrg 	 We have to use the last argument as our selector.  */
10136ac495dSmrg       if (strcasecmp (argv[0], "hwmult") == 0)
10236ac495dSmrg 	{
10336ac495dSmrg 	  static struct hwmult_options
10436ac495dSmrg 	    {
10536ac495dSmrg 	      const char * name;
10636ac495dSmrg 	      const char * lib;
10736ac495dSmrg 	    } hwmult_options[] =
10836ac495dSmrg 	    {
10936ac495dSmrg 	      { "none", "-lmul_none" },
11036ac495dSmrg 	      { "auto", "-lmul_AUTO" }, /* Should not see this one... */
11136ac495dSmrg 	      { "16bit", "-lmul_16" },
11236ac495dSmrg 	      { "32bit", "-lmul_32" },
11336ac495dSmrg 	      { "f5series", "-lmul_f5" }
11436ac495dSmrg 	    };
11536ac495dSmrg 
11636ac495dSmrg 	for (i = ARRAY_SIZE (hwmult_options); i--;)
11736ac495dSmrg 	  if (strcasecmp (argv[argc - 1], hwmult_options[i].name) == 0)
11836ac495dSmrg 	    return hwmult_options[i].lib;
11936ac495dSmrg 	}
12036ac495dSmrg       else if (strcasecmp (argv[0], "mcu") == 0)
12136ac495dSmrg 	{
122*8feb0f0bSmrg 	  msp430_extract_mcu_data (argv[argc - 1]);
123*8feb0f0bSmrg 	  if (extracted_mcu_data.name != NULL)
12436ac495dSmrg 	    {
125*8feb0f0bSmrg 	      switch (extracted_mcu_data.hwmpy)
12636ac495dSmrg 		{
12736ac495dSmrg 		case 0: return "-lmul_none";
12836ac495dSmrg 		case 2:
12936ac495dSmrg 		case 1: return "-lmul_16";
13036ac495dSmrg 		case 4: return "-lmul_32";
13136ac495dSmrg 		case 8: return "-lmul_f5";
13236ac495dSmrg 		default:
133*8feb0f0bSmrg 		  /* We have already checked the hwmpy values for
134*8feb0f0bSmrg 		     validity in msp430_extract_mcu_data.  */
135*8feb0f0bSmrg 		  gcc_unreachable ();
13636ac495dSmrg 		  break;
13736ac495dSmrg 		}
13836ac495dSmrg 	    }
13936ac495dSmrg 	}
14036ac495dSmrg       else
141*8feb0f0bSmrg 	error ("unexpected first argument to msp430_select_hwmult_lib: %s",
142*8feb0f0bSmrg 	       argv[0]);
14336ac495dSmrg       break;
14436ac495dSmrg 
14536ac495dSmrg     case 0:
14636ac495dSmrg       error ("msp430_select_hwmult_lib needs one or more arguments");
14736ac495dSmrg       break;
14836ac495dSmrg     }
14936ac495dSmrg 
15036ac495dSmrg   return "-lmul_none";
15136ac495dSmrg }
152*8feb0f0bSmrg 
153*8feb0f0bSmrg /* Spec function.  Used to place the path to the MSP430-GCC support files
154*8feb0f0bSmrg    on the command line, prefixed with "-L", so the linker finds the linker
155*8feb0f0bSmrg    scripts in that directory.  */
156*8feb0f0bSmrg const char *
msp430_get_linker_devices_include_path(int argc ATTRIBUTE_UNUSED,const char ** argv ATTRIBUTE_UNUSED)157*8feb0f0bSmrg msp430_get_linker_devices_include_path (int argc ATTRIBUTE_UNUSED,
158*8feb0f0bSmrg 					const char **argv ATTRIBUTE_UNUSED)
159*8feb0f0bSmrg {
160*8feb0f0bSmrg   char *devices_csv_path;
161*8feb0f0bSmrg   if (msp430_check_env_var_for_devices (&devices_csv_path))
162*8feb0f0bSmrg     return NULL;
163*8feb0f0bSmrg   return concat ("-L", msp430_dirname (devices_csv_path), NULL);
164*8feb0f0bSmrg }
165*8feb0f0bSmrg 
166*8feb0f0bSmrg /* Spec function.  Propagate -m{code,data}-region= to the linker, unless the
167*8feb0f0bSmrg    lower region has been specified without -muse-lower-region-prefix also being
168*8feb0f0bSmrg    used.  */
169*8feb0f0bSmrg const char *
msp430_propagate_region_opt(int argc,const char ** argv)170*8feb0f0bSmrg msp430_propagate_region_opt (int argc, const char **argv)
171*8feb0f0bSmrg {
172*8feb0f0bSmrg   if (strcmp (argv[0], "lower") != 0)
173*8feb0f0bSmrg     return argv[0];
174*8feb0f0bSmrg   else if ((argc == 2) && (strcmp (argv[1], "-muse-lower-region-prefix") == 0))
175*8feb0f0bSmrg     return argv[0]; /* argv[0] == "lower".  */
176*8feb0f0bSmrg   return "none";
177*8feb0f0bSmrg }
178