]>
Commit | Line | Data |
---|---|---|
04a9ae28 | 1 | /* Subroutines for the gcc driver. |
7adcbafe | 2 | Copyright (C) 2015-2022 Free Software Foundation, Inc. |
04a9ae28 NC |
3 | Contributed by Georg-Johann Lay <avr@gjlay.de> |
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 | ||
8fcc61f8 RS |
21 | #define IN_TARGET_CODE 1 |
22 | ||
04a9ae28 NC |
23 | #include "config.h" |
24 | #include "system.h" | |
25 | #include "coretypes.h" | |
26 | #include "diagnostic.h" | |
27 | #include "tm.h" | |
e37e2bb1 | 28 | #include "msp430-devices.h" |
04a9ae28 | 29 | |
e37e2bb1 JL |
30 | /* This spec function is called if the user has provided an -mmcu option without |
31 | an -mcpu option. It will place the correct -mcpu option for the given -mmcu | |
32 | onto the command line, to ensure the correct ISA multilib is selected. */ | |
33 | const char * | |
34 | msp430_select_cpu (int argc, const char ** argv) | |
04a9ae28 | 35 | { |
e37e2bb1 JL |
36 | if (argc == 0) |
37 | { | |
43bfd4e8 | 38 | error ("expected an argument to %<msp430_select_cpu%>"); |
e37e2bb1 JL |
39 | return NULL; |
40 | } | |
41 | msp430_extract_mcu_data (argv[0]); | |
42 | if (extracted_mcu_data.name != NULL) | |
43 | { | |
44 | switch (extracted_mcu_data.revision) | |
45 | { | |
46 | case 0: return "-mcpu=msp430"; | |
47 | case 1: return "-mcpu=msp430x"; | |
48 | case 2: return "-mcpu=msp430xv2"; | |
49 | default: | |
81a8845c | 50 | gcc_unreachable (); |
e37e2bb1 JL |
51 | } |
52 | } | |
53 | /* MCU wasn't found, the compiler proper will warn about this. */ | |
54 | return NULL; | |
04a9ae28 | 55 | } |
04a9ae28 | 56 | |
d5c94995 JL |
57 | /* Spec function to set a global variable to a specific value in the driver. |
58 | The first argument is the variable name, and the second is the value to set | |
59 | it to. | |
60 | Currently only "msp430_warn_devices_csv" and "msp430_devices_csv_loc" are | |
61 | supported. | |
62 | The intention is that we can take a "Target" option and set the variable | |
63 | associated with it in the driver as well. Whilst the driver sees "Target" | |
64 | options, it does not set the variables associated with that option. */ | |
65 | const char * | |
66 | msp430_set_driver_var (int argc, const char ** argv) | |
67 | { | |
68 | if (argc != 2) | |
69 | error ("%<msp430_set_driver_var%> expects 2 arguments"); | |
70 | else if (strcmp (argv[0], "msp430_warn_devices_csv") == 0) | |
71 | msp430_warn_devices_csv = atoi (argv[1]); | |
72 | else if (strcmp (argv[0], "msp430_devices_csv_loc") == 0) | |
73 | msp430_devices_csv_loc = argv[1]; | |
74 | else | |
75 | error ("unhandled arguments %qs and %qs to %<msp430_set_driver_var%>", | |
76 | argv[0], argv[1]); | |
77 | return NULL; | |
78 | } | |
79 | ||
04a9ae28 NC |
80 | /* Implement spec function `msp430_hwmult_libĀ“. */ |
81 | ||
82 | const char * | |
43bfd4e8 JL |
83 | msp430_select_hwmult_lib (int argc ATTRIBUTE_UNUSED, |
84 | const char ** argv ATTRIBUTE_UNUSED) | |
04a9ae28 NC |
85 | { |
86 | int i; | |
87 | ||
88 | switch (argc) | |
81a8845c JL |
89 | { |
90 | case 1: | |
91 | if (strcasecmp (argv[0], "default")) | |
92 | error ("unexpected argument to msp430_select_hwmult_lib: %s", argv[0]); | |
93 | break; | |
04a9ae28 | 94 | |
81a8845c JL |
95 | default: |
96 | /* We can get three or more arguments passed to this function. | |
97 | This happens when the same option is repeated on the command line. | |
98 | For example: | |
99 | msp430-elf-gcc -mhwmult=none -mhwmult=16bit foo.c | |
100 | We have to use the last argument as our selector. */ | |
101 | if (strcasecmp (argv[0], "hwmult") == 0) | |
04a9ae28 | 102 | { |
81a8845c JL |
103 | static struct hwmult_options |
104 | { | |
105 | const char * name; | |
106 | const char * lib; | |
107 | } hwmult_options[] = | |
108 | { | |
109 | { "none", "-lmul_none" }, | |
110 | { "auto", "-lmul_AUTO" }, /* Should not see this one... */ | |
111 | { "16bit", "-lmul_16" }, | |
112 | { "32bit", "-lmul_32" }, | |
113 | { "f5series", "-lmul_f5" } | |
114 | }; | |
04a9ae28 NC |
115 | |
116 | for (i = ARRAY_SIZE (hwmult_options); i--;) | |
117 | if (strcasecmp (argv[argc - 1], hwmult_options[i].name) == 0) | |
118 | return hwmult_options[i].lib; | |
81a8845c JL |
119 | } |
120 | else if (strcasecmp (argv[0], "mcu") == 0) | |
121 | { | |
122 | msp430_extract_mcu_data (argv[argc - 1]); | |
123 | if (extracted_mcu_data.name != NULL) | |
04a9ae28 | 124 | { |
e37e2bb1 | 125 | switch (extracted_mcu_data.hwmpy) |
04a9ae28 NC |
126 | { |
127 | case 0: return "-lmul_none"; | |
128 | case 2: | |
129 | case 1: return "-lmul_16"; | |
130 | case 4: return "-lmul_32"; | |
131 | case 8: return "-lmul_f5"; | |
132 | default: | |
81a8845c JL |
133 | /* We have already checked the hwmpy values for |
134 | validity in msp430_extract_mcu_data. */ | |
135 | gcc_unreachable (); | |
04a9ae28 NC |
136 | break; |
137 | } | |
138 | } | |
81a8845c JL |
139 | } |
140 | else | |
43bfd4e8 JL |
141 | error ("unexpected first argument to msp430_select_hwmult_lib: %s", |
142 | argv[0]); | |
81a8845c JL |
143 | break; |
144 | ||
145 | case 0: | |
146 | error ("msp430_select_hwmult_lib needs one or more arguments"); | |
147 | break; | |
148 | } | |
04a9ae28 | 149 | |
04a9ae28 NC |
150 | return "-lmul_none"; |
151 | } | |
8682b1a5 | 152 | |
d7eabfd4 JL |
153 | /* Spec function. Used to place the path to the MSP430-GCC support files |
154 | on the command line, prefixed with "-L", so the linker finds the linker | |
155 | scripts in that directory. */ | |
156 | const char * | |
157 | msp430_get_linker_devices_include_path (int argc ATTRIBUTE_UNUSED, | |
158 | const char **argv ATTRIBUTE_UNUSED) | |
159 | { | |
160 | char *devices_csv_path; | |
161 | if (msp430_check_env_var_for_devices (&devices_csv_path)) | |
162 | return NULL; | |
163 | return concat ("-L", msp430_dirname (devices_csv_path), NULL); | |
164 | } | |
165 | ||
8682b1a5 JL |
166 | /* Spec function. Propagate -m{code,data}-region= to the linker, unless the |
167 | lower region has been specified without -muse-lower-region-prefix also being | |
168 | used. */ | |
169 | const char * | |
170 | msp430_propagate_region_opt (int argc, const char **argv) | |
171 | { | |
172 | if (strcmp (argv[0], "lower") != 0) | |
173 | return argv[0]; | |
174 | else if ((argc == 2) && (strcmp (argv[1], "-muse-lower-region-prefix") == 0)) | |
175 | return argv[0]; /* argv[0] == "lower". */ | |
176 | return "none"; | |
177 | } |