]>
Commit | Line | Data |
---|---|---|
f6a83b4a | 1 | /* GCC backend definitions for the TI MSP430 Processor |
99dee823 | 2 | Copyright (C) 2012-2021 Free Software Foundation, Inc. |
f6a83b4a DD |
3 | Contributed by Red Hat. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it | |
8 | under the terms of the GNU General Public License as published | |
9 | by the Free Software Foundation; either version 3, or (at your | |
10 | option) any later version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT | |
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
15 | 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 | \f | |
21 | ||
22 | /* Run-time Target Specification */ | |
23 | ||
24 | /* True if the MSP430x extensions are enabled. */ | |
25 | #ifndef IN_LIBGCC2 | |
26 | extern bool msp430x; | |
27 | #endif | |
28 | ||
81a8845c JL |
29 | #define TARGET_CPU_CPP_BUILTINS() \ |
30 | do \ | |
31 | { \ | |
32 | builtin_define ("NO_TRAMPOLINES"); \ | |
f6a83b4a | 33 | builtin_define ("__MSP430__"); \ |
50cfbf99 | 34 | builtin_define (msp430_mcu_name ()); \ |
f6a83b4a DD |
35 | if (msp430x) \ |
36 | { \ | |
37 | builtin_define ("__MSP430X__"); \ | |
38 | builtin_assert ("cpu=MSP430X"); \ | |
39 | if (TARGET_LARGE) \ | |
40 | builtin_define ("__MSP430X_LARGE__"); \ | |
41 | } \ | |
42 | else \ | |
43 | builtin_assert ("cpu=MSP430"); \ | |
81a8845c | 44 | } \ |
f6a83b4a DD |
45 | while (0) |
46 | ||
a9046e98 JL |
47 | /* For the "c" language where exceptions are implicitly disabled, use |
48 | crt*_no_eh.o unless -fexceptions is passed. For other languages, only use | |
49 | crt*_no_eh.o if -fno-exceptions is explicitly passed. */ | |
f6a83b4a | 50 | #undef STARTFILE_SPEC |
43bfd4e8 | 51 | #define STARTFILE_SPEC "%{pg:gcrt0.o%s}" \ |
a9046e98 JL |
52 | "%{!pg:%{minrt:crt0-minrt.o%s}%{!minrt:crt0.o%s}} " \ |
53 | "%{!minrt:%{,c:%{!fexceptions:crtbegin_no_eh.o%s; :crtbegin.o%s}; " \ | |
54 | ":%{fno-exceptions:crtbegin_no_eh.o%s; :crtbegin.o%s}}}" | |
f6a83b4a DD |
55 | |
56 | /* -lgcc is included because crtend.o needs __mspabi_func_epilog_1. */ | |
57 | #undef ENDFILE_SPEC | |
a9046e98 JL |
58 | #define ENDFILE_SPEC \ |
59 | "%{!minrt:%{,c:%{!fexceptions:crtend_no_eh.o%s; :crtend.o%s}; " \ | |
60 | ":%{fno-exceptions:crtend_no_eh.o%s; :crtend.o%s}}} " \ | |
378a578a | 61 | "%{minrt:%:if-exists(crtn-minrt.o%s)}%{!minrt:%:if-exists(crtn.o%s)} -lgcc" |
f6a83b4a DD |
62 | |
63 | #define ASM_SPEC "-mP " /* Enable polymorphic instructions. */ \ | |
e37e2bb1 | 64 | "%{mcpu=*:-mcpu=%*} " /* Pass the CPU type on to the assembler. */ \ |
f6a83b4a | 65 | "%{mrelax=-mQ} " /* Pass the relax option on to the assembler. */ \ |
43bfd4e8 JL |
66 | /* Tell the assembler if we are building for the LARGE pointer model. */ \ |
67 | "%{mlarge:-ml} " \ | |
43bfd4e8 JL |
68 | "%{msilicon-errata=*:-msilicon-errata=%*} " \ |
69 | "%{msilicon-errata-warn=*:-msilicon-errata-warn=%*} " \ | |
70 | /* Create DWARF line number sections for -ffunction-sections. */ \ | |
71 | "%{ffunction-sections:-gdwarf-sections} " \ | |
72 | "%{mdata-region=*:-mdata-region=%*} " | |
f6a83b4a DD |
73 | |
74 | /* Enable linker section garbage collection by default, unless we | |
75 | are creating a relocatable binary (gc does not work) or debugging | |
43bfd4e8 JL |
76 | is enabled (the GDB testsuite relies upon unused entities not being |
77 | deleted). */ | |
39459216 | 78 | #define LINK_SPEC "%{mrelax:--relax} %{mlarge:%{!r:%{!g:--gc-sections}}} " \ |
8682b1a5 JL |
79 | "%{mcode-region=*:--code-region=%:" \ |
80 | "msp430_propagate_region_opt(%* %{muse-lower-region-prefix})} " \ | |
81 | "%{mdata-region=*:--data-region=%:" \ | |
82 | "msp430_propagate_region_opt(%* %{muse-lower-region-prefix})} " \ | |
02afb6a9 JL |
83 | "%:msp430_get_linker_devices_include_path() " \ |
84 | "%{mtiny-printf:--wrap puts --wrap printf} " | |
f6a83b4a | 85 | |
49c432df JL |
86 | #define DRIVER_SELF_SPECS \ |
87 | " %{!mlarge:%{mcode-region=*:%{mdata-region=*:%e-mcode-region and " \ | |
88 | "-mdata-region require the large memory model (-mlarge)}}}" \ | |
89 | " %{!mlarge:%{mcode-region=*:" \ | |
90 | "%e-mcode-region requires the large memory model (-mlarge)}}" \ | |
91 | " %{!mlarge:%{mdata-region=*:" \ | |
e37e2bb1 | 92 | "%e-mdata-region requires the large memory model (-mlarge)}}" \ |
d5c94995 JL |
93 | " %{mno-warn-devices-csv:%:msp430_set_driver_var(msp430_warn_devices_csv 0)}"\ |
94 | " %{mdevices-csv-loc=*:%:msp430_set_driver_var(msp430_devices_csv_loc %*)}"\ | |
95 | " %{I*:%:msp430_check_path_for_devices(%{I*:%*})}" \ | |
96 | " %{L*:%:msp430_check_path_for_devices(%{L*:%*})}" \ | |
e37e2bb1 | 97 | " %{!mcpu=*:%{mmcu=*:%:msp430_select_cpu(%{mmcu=*:%*})}}" |
49c432df | 98 | |
04a9ae28 | 99 | extern const char * msp430_select_hwmult_lib (int, const char **); |
e37e2bb1 | 100 | extern const char * msp430_select_cpu (int, const char **); |
d5c94995 JL |
101 | extern const char * msp430_set_driver_var (int, const char **); |
102 | extern const char * msp430_check_path_for_devices (int, const char **); | |
8682b1a5 | 103 | extern const char *msp430_propagate_region_opt (int, const char **); |
d7eabfd4 | 104 | extern const char *msp430_get_linker_devices_include_path (int, const char **); |
e37e2bb1 | 105 | |
8682b1a5 JL |
106 | /* There must be a trailing comma after the last item, see gcc.c |
107 | "static_spec_functions". */ | |
04a9ae28 | 108 | # define EXTRA_SPEC_FUNCTIONS \ |
e37e2bb1 | 109 | { "msp430_hwmult_lib", msp430_select_hwmult_lib }, \ |
d5c94995 JL |
110 | { "msp430_select_cpu", msp430_select_cpu }, \ |
111 | { "msp430_set_driver_var", msp430_set_driver_var }, \ | |
8682b1a5 | 112 | { "msp430_check_path_for_devices", msp430_check_path_for_devices }, \ |
d7eabfd4 JL |
113 | { "msp430_propagate_region_opt", msp430_propagate_region_opt }, \ |
114 | { "msp430_get_linker_devices_include_path", \ | |
115 | msp430_get_linker_devices_include_path }, | |
04a9ae28 NC |
116 | |
117 | /* Specify the libraries to include on the linker command line. | |
118 | ||
119 | Selecting the hardware multiply library to use is quite complex. | |
120 | If the user has specified -mhwmult=FOO then the mapping is quite | |
121 | easy (and could be handled here in the SPEC string), unless FOO | |
122 | is set to AUTO. In this case the -mmcu= option must be consulted | |
123 | instead. If the -mhwmult= option is not specified then the -mmcu= | |
124 | option must then be examined. If neither -mhwmult= nor -mmcu= are | |
125 | specified then a default hardware multiply library is used. | |
126 | ||
127 | Examining the -mmcu=FOO option is difficult, and it is so this | |
128 | reason that a spec function is used. There are so many possible | |
129 | values of FOO that a table is used to look up the name and map | |
130 | it to a hardware multiply library. This table (in device-msp430.c) | |
131 | must be kept in sync with the same table in msp430.c. */ | |
f6a83b4a DD |
132 | #undef LIB_SPEC |
133 | #define LIB_SPEC " \ | |
134 | --start-group \ | |
43bfd4e8 JL |
135 | %{mhwmult=auto:%{mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*});\ |
136 | :%:msp430_hwmult_lib(default)}; \ | |
04a9ae28 NC |
137 | mhwmult=*:%:msp430_hwmult_lib(hwmult %{mhwmult=*:%*}); \ |
138 | mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*}); \ | |
139 | :%:msp430_hwmult_lib(default)} \ | |
f6a83b4a DD |
140 | -lc \ |
141 | -lgcc \ | |
4f50b9ff | 142 | -lcrt \ |
f6a83b4a | 143 | %{msim:-lsim} \ |
04a9ae28 | 144 | %{!msim:-lnosys} \ |
f6a83b4a | 145 | --end-group \ |
949ad971 | 146 | %{!T*:%{!msim:%{mmcu=*:--script=%*.ld}}} \ |
50cfbf99 | 147 | %{!T*:%{msim:%{mlarge:%Tmsp430xl-sim.ld}%{!mlarge:%Tmsp430-sim.ld}}} \ |
f6a83b4a DD |
148 | " |
149 | \f | |
f6a83b4a DD |
150 | /* Storage Layout */ |
151 | ||
152 | #define BITS_BIG_ENDIAN 0 | |
153 | #define BYTES_BIG_ENDIAN 0 | |
154 | #define WORDS_BIG_ENDIAN 0 | |
155 | ||
156 | ||
157 | #ifdef IN_LIBGCC2 | |
158 | /* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits). */ | |
159 | #define UNITS_PER_WORD 4 | |
160 | /* We have a problem with libgcc2. It only defines two versions of | |
161 | each function, one for "int" and one for "long long". Ie it assumes | |
162 | that "sizeof (int) == sizeof (long)". For the MSP430 this is not true | |
163 | and we need a third set of functions. We explicitly define | |
164 | LIBGCC2_UNITS_PER_WORD here so that it is clear that we are expecting | |
165 | to get the SI and DI versions from the libgcc2.c sources, and we | |
166 | provide our own set of HI functions, which is why this | |
167 | definition is surrounded by #ifndef..#endif. */ | |
168 | #ifndef LIBGCC2_UNITS_PER_WORD | |
169 | #define LIBGCC2_UNITS_PER_WORD 4 | |
170 | #endif | |
171 | #else | |
172 | /* Actual width of a word, in units (bytes). */ | |
173 | #define UNITS_PER_WORD 2 | |
174 | #endif | |
175 | ||
176 | #define SHORT_TYPE_SIZE 16 | |
177 | #define INT_TYPE_SIZE 16 | |
178 | #define LONG_TYPE_SIZE 32 | |
179 | #define LONG_LONG_TYPE_SIZE 64 | |
180 | ||
181 | #define FLOAT_TYPE_SIZE 32 | |
182 | #define DOUBLE_TYPE_SIZE 64 | |
183 | #define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/ | |
184 | ||
f6a83b4a DD |
185 | #define DEFAULT_SIGNED_CHAR 0 |
186 | ||
187 | #define STRICT_ALIGNMENT 1 | |
188 | #define FUNCTION_BOUNDARY 16 | |
189 | #define BIGGEST_ALIGNMENT 16 | |
190 | #define STACK_BOUNDARY 16 | |
191 | #define PARM_BOUNDARY 8 | |
192 | #define PCC_BITFIELD_TYPE_MATTERS 1 | |
193 | ||
194 | #define STACK_GROWS_DOWNWARD 1 | |
195 | #define FRAME_GROWS_DOWNWARD 1 | |
196 | #define FIRST_PARM_OFFSET(FNDECL) 0 | |
197 | ||
198 | #define MAX_REGS_PER_ADDRESS 1 | |
199 | ||
200 | #define Pmode (TARGET_LARGE ? PSImode : HImode) | |
c32ab325 DD |
201 | #define POINTER_SIZE (TARGET_LARGE ? 20 : 16) |
202 | /* This is just for .eh_frame, to match bfd. */ | |
203 | #define PTR_SIZE (TARGET_LARGE ? 4 : 2) | |
f6a83b4a DD |
204 | #define POINTERS_EXTEND_UNSIGNED 1 |
205 | ||
e7b78f72 JL |
206 | /* TARGET_VTABLE_ENTRY_ALIGN defaults to POINTER_SIZE, which is 20 for |
207 | TARGET_LARGE. Pointer alignment is always 16 for MSP430, so set explicitly | |
208 | here. */ | |
209 | #define TARGET_VTABLE_ENTRY_ALIGN 16 | |
210 | ||
f6a83b4a DD |
211 | #define ADDR_SPACE_NEAR 1 |
212 | #define ADDR_SPACE_FAR 2 | |
213 | ||
214 | #define REGISTER_TARGET_PRAGMAS() msp430_register_pragmas() | |
215 | ||
216 | #if 1 /* XXX */ | |
217 | /* Define this macro if it is advisable to hold scalars in registers | |
218 | in a wider mode than that declared by the program. In such cases, | |
219 | the value is constrained to be within the bounds of the declared | |
220 | type, but kept valid in the wider mode. The signedness of the | |
221 | extension may differ from that of the type. */ | |
222 | ||
223 | #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ | |
224 | if (GET_MODE_CLASS (MODE) == MODE_INT \ | |
225 | && GET_MODE_SIZE (MODE) < 2) \ | |
226 | (MODE) = HImode; | |
227 | #endif | |
228 | \f | |
229 | /* Layout of Source Language Data Types */ | |
230 | ||
231 | #undef SIZE_TYPE | |
5e580306 JL |
232 | #define SIZE_TYPE (TARGET_LARGE \ |
233 | ? "__int20__ unsigned" \ | |
234 | : "unsigned int") | |
f6a83b4a | 235 | #undef PTRDIFF_TYPE |
5e580306 | 236 | #define PTRDIFF_TYPE (TARGET_LARGE ? "__int20__" : "int") |
f6a83b4a DD |
237 | #undef WCHAR_TYPE |
238 | #define WCHAR_TYPE "long int" | |
239 | #undef WCHAR_TYPE_SIZE | |
240 | #define WCHAR_TYPE_SIZE BITS_PER_WORD | |
241 | #define FUNCTION_MODE HImode | |
242 | #define CASE_VECTOR_MODE Pmode | |
243 | #define HAS_LONG_COND_BRANCH 0 | |
244 | #define HAS_LONG_UNCOND_BRANCH 0 | |
245 | ||
54896b10 JL |
246 | /* The cost of a branch sequence is roughly 3 "cheap" instructions. */ |
247 | #define BRANCH_COST(speed_p, predictable_p) 3 | |
248 | ||
249 | /* Override the default BRANCH_COST heuristic to indicate that it is preferable | |
250 | to retain short-circuit operations, this results in significantly better | |
251 | codesize and performance. */ | |
252 | #define LOGICAL_OP_NON_SHORT_CIRCUIT 0 | |
253 | ||
f6a83b4a | 254 | #define LOAD_EXTEND_OP(M) ZERO_EXTEND |
3f02735b | 255 | #define WORD_REGISTER_OPERATIONS 1 |
f6a83b4a DD |
256 | |
257 | #define MOVE_MAX 8 | |
f6a83b4a DD |
258 | |
259 | #define INCOMING_RETURN_ADDR_RTX \ | |
260 | msp430_incoming_return_addr_rtx () | |
261 | ||
262 | #define RETURN_ADDR_RTX(COUNT, FA) \ | |
263 | msp430_return_addr_rtx (COUNT) | |
264 | ||
f6a83b4a | 265 | #define SLOW_BYTE_ACCESS 0 |
111afded JL |
266 | |
267 | /* Calling a constant function address costs the same number of clock | |
268 | cycles as calling an address stored in a register. However, in terms of | |
269 | instruction length, calling a constant address is more expensive. */ | |
270 | #define NO_FUNCTION_CSE (optimize >= 2 && !optimize_size) | |
f6a83b4a DD |
271 | \f |
272 | ||
273 | /* Register Usage */ | |
274 | ||
275 | /* gas doesn't recognize PC (R0), SP (R1), and SR (R2) as register | |
276 | names. */ | |
277 | #define REGISTER_NAMES \ | |
278 | { \ | |
279 | "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \ | |
280 | "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", \ | |
281 | "argptr" \ | |
282 | } | |
283 | ||
37816988 JL |
284 | /* Allow lowercase "r" to be used in register names instead of upper |
285 | case "R". */ | |
286 | #define ADDITIONAL_REGISTER_NAMES \ | |
287 | { \ | |
288 | { "r0", 0 }, \ | |
289 | { "r1", 1 }, \ | |
290 | { "r2", 2 }, \ | |
291 | { "r3", 3 }, \ | |
292 | { "r4", 4 }, \ | |
293 | { "r5", 5 }, \ | |
294 | { "r6", 6 }, \ | |
295 | { "r7", 7 }, \ | |
296 | { "r8", 8 }, \ | |
297 | { "r9", 9 }, \ | |
298 | { "r10", 10 }, \ | |
299 | { "r11", 11 }, \ | |
300 | { "r12", 12 }, \ | |
301 | { "r13", 13 }, \ | |
302 | { "r14", 14 }, \ | |
303 | { "r15", 15 } \ | |
304 | } | |
305 | ||
f6a83b4a DD |
306 | enum reg_class |
307 | { | |
308 | NO_REGS, | |
309 | R12_REGS, | |
310 | R13_REGS, | |
311 | GEN_REGS, | |
312 | ALL_REGS, | |
313 | LIM_REG_CLASSES | |
314 | }; | |
315 | ||
316 | #define REG_CLASS_NAMES \ | |
317 | { \ | |
318 | "NO_REGS", \ | |
319 | "R12_REGS", \ | |
320 | "R13_REGS", \ | |
321 | "GEN_REGS", \ | |
322 | "ALL_REGS" \ | |
323 | } | |
324 | ||
325 | #define REG_CLASS_CONTENTS \ | |
326 | { \ | |
327 | 0x00000000, \ | |
328 | 0x00001000, \ | |
329 | 0x00002000, \ | |
f1b0a1dd | 330 | 0x0000fff3, \ |
f6a83b4a DD |
331 | 0x0001ffff \ |
332 | } | |
333 | ||
f1b0a1dd JL |
334 | /* GENERAL_REGS just means that the "g" and "r" constraints can use these |
335 | registers. | |
336 | Even though R0 (PC) and R1 (SP) are not "general" in that they can be used | |
337 | for any purpose by the register allocator, they are general in that they can | |
338 | be used by any instruction in any addressing mode. */ | |
f6a83b4a DD |
339 | #define GENERAL_REGS GEN_REGS |
340 | #define BASE_REG_CLASS GEN_REGS | |
341 | #define INDEX_REG_CLASS GEN_REGS | |
342 | #define N_REG_CLASSES (int) LIM_REG_CLASSES | |
343 | ||
81a8845c JL |
344 | #define PC_REGNUM 0 |
345 | #define STACK_POINTER_REGNUM 1 | |
346 | #define CC_REGNUM 2 | |
f6a83b4a DD |
347 | #define FRAME_POINTER_REGNUM 4 /* not usually used, call preserved */ |
348 | #define ARG_POINTER_REGNUM 16 | |
349 | #define STATIC_CHAIN_REGNUM 5 /* FIXME */ | |
350 | ||
351 | #define FIRST_PSEUDO_REGISTER 17 | |
352 | ||
f1b0a1dd JL |
353 | #define REGNO_REG_CLASS(REGNO) (REGNO != 2 \ |
354 | && REGNO != 3 \ | |
355 | && REGNO < 17 \ | |
f6a83b4a DD |
356 | ? GEN_REGS : NO_REGS) |
357 | ||
358 | #define TRAMPOLINE_SIZE 4 /* FIXME */ | |
359 | #define TRAMPOLINE_ALIGNMENT 16 /* FIXME */ | |
360 | ||
361 | #define ELIMINABLE_REGS \ | |
362 | {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ | |
363 | { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ | |
364 | { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} | |
365 | ||
366 | #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ | |
367 | (OFFSET) = msp430_initial_elimination_offset ((FROM), (TO)) | |
368 | ||
369 | ||
370 | #define FUNCTION_ARG_REGNO_P(N) ((N) >= 8 && (N) < ARG_POINTER_REGNUM) | |
371 | #define DEFAULT_PCC_STRUCT_RETURN 0 | |
372 | ||
373 | /* 1 == register can't be used by gcc, in general | |
374 | 0 == register can be used by gcc, in general */ | |
375 | #define FIXED_REGISTERS \ | |
376 | { \ | |
377 | 1,0,1,1, 0,0,0,0, \ | |
378 | 0,0,0,0, 0,0,0,0, \ | |
379 | 1, \ | |
380 | } | |
381 | ||
382 | /* 1 == value changes across function calls | |
383 | 0 == value is the same after a call */ | |
384 | /* R4 through R10 are callee-saved */ | |
385 | #define CALL_USED_REGISTERS \ | |
386 | { \ | |
387 | 1,0,1,1, 0,0,0,0, \ | |
388 | 0,0,0,1, 1,1,1,1, \ | |
389 | 1, \ | |
390 | } | |
391 | ||
392 | #define REG_ALLOC_ORDER \ | |
393 | { 12, 13, 14, 15, 10, 9, 8, 7, 6, 5, 4, 11, 0, 1, 2, 3, 16 } | |
394 | /* { 11, 15, 14, 13, 12, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3, 16 }*/ | |
395 | ||
396 | #define REGNO_OK_FOR_BASE_P(regno) 1 | |
397 | #define REGNO_OK_FOR_INDEX_P(regno) 1 | |
398 | ||
399 | \f | |
400 | ||
cad055a4 NC |
401 | typedef struct |
402 | { | |
f6a83b4a DD |
403 | /* These two are the current argument status. */ |
404 | char reg_used[4]; | |
405 | #define CA_FIRST_REG 12 | |
406 | char can_split; | |
407 | /* These two are temporaries used internally. */ | |
408 | char start_reg; | |
409 | char reg_count; | |
410 | char mem_count; | |
411 | char special_p; | |
412 | } CUMULATIVE_ARGS; | |
413 | ||
414 | #define INIT_CUMULATIVE_ARGS(CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ | |
415 | msp430_init_cumulative_args (&CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) | |
416 | ||
417 | \f | |
418 | /* FIXME */ | |
419 | #define NO_PROFILE_COUNTERS 1 | |
420 | #define PROFILE_BEFORE_PROLOGUE 1 | |
421 | ||
422 | #define FUNCTION_PROFILER(FILE, LABELNO) \ | |
423 | fprintf (FILE, "\tcall\t__mcount\n"); | |
424 | \f | |
f6a83b4a DD |
425 | /* Exception Handling */ |
426 | ||
427 | /* R12,R13,R14 - EH data | |
428 | R15 - stack adjustment */ | |
429 | ||
430 | #define EH_RETURN_DATA_REGNO(N) \ | |
431 | (((N) < 3) ? ((N) + 12) : INVALID_REGNUM) | |
432 | ||
433 | #define EH_RETURN_HANDLER_RTX \ | |
43bfd4e8 JL |
434 | gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, SP_REGNO), \ |
435 | gen_rtx_REG (Pmode, 15))) | |
f6a83b4a DD |
436 | |
437 | #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 15) | |
438 | ||
439 | #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4 | |
440 | ||
441 | \f | |
442 | /* Stack Layout and Calling Conventions */ | |
443 | ||
444 | \f | |
445 | /* Addressing Modes */ | |
446 | ||
447 | \f | |
448 | ||
449 | #define TEXT_SECTION_ASM_OP ".text" | |
450 | #define DATA_SECTION_ASM_OP ".data" | |
451 | #define BSS_SECTION_ASM_OP "\t.section .bss" | |
452 | ||
453 | #define ASM_COMMENT_START " ;" | |
454 | #define ASM_APP_ON "" | |
455 | #define ASM_APP_OFF "" | |
456 | #define LOCAL_LABEL_PREFIX ".L" | |
457 | #undef USER_LABEL_PREFIX | |
458 | #define USER_LABEL_PREFIX "" | |
459 | ||
460 | #define GLOBAL_ASM_OP "\t.global\t" | |
461 | ||
462 | #define ASM_OUTPUT_LABELREF(FILE, SYM) msp430_output_labelref ((FILE), (SYM)) | |
463 | ||
464 | #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ | |
465 | fprintf (FILE, "\t.long .L%d\n", VALUE) | |
466 | ||
467 | /* This is how to output an element of a case-vector that is relative. | |
468 | Note: The local label referenced by the "3b" below is emitted by | |
469 | the tablejump insn. */ | |
470 | ||
471 | #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ | |
472 | fprintf (FILE, "\t.long .L%d - 1b\n", VALUE) | |
473 | ||
474 | ||
475 | #define ASM_OUTPUT_ALIGN(STREAM, LOG) \ | |
476 | do \ | |
477 | { \ | |
478 | if ((LOG) == 0) \ | |
81a8845c | 479 | break; \ |
f6a83b4a DD |
480 | fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \ |
481 | } \ | |
482 | while (0) | |
483 | ||
484 | #define JUMP_TABLES_IN_TEXT_SECTION 1 | |
485 | \f | |
486 | #undef DWARF2_ADDR_SIZE | |
487 | #define DWARF2_ADDR_SIZE 4 | |
488 | ||
c32ab325 | 489 | #define INCOMING_FRAME_SP_OFFSET (TARGET_LARGE ? 4 : 2) |
f6a83b4a DD |
490 | |
491 | #undef PREFERRED_DEBUGGING_TYPE | |
492 | #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG | |
493 | ||
494 | #define DWARF2_ASM_LINE_DEBUG_INFO 1 | |
495 | ||
496 | /* Prevent reload (and others) from choosing HImode stack slots | |
497 | when spilling hard registers when they may contain PSImode values. */ | |
498 | #define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \ | |
43bfd4e8 | 499 | ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode \ |
737d6a1a | 500 | : choose_hard_reg_mode ((REGNO), (NREGS), NULL)) |
f6a83b4a | 501 | |
f6a83b4a | 502 | #define ACCUMULATE_OUTGOING_ARGS 1 |
d30d00a2 | 503 | |
28987d8b JL |
504 | #define HAVE_POST_INCREMENT 1 |
505 | ||
506 | /* This (unsurprisingly) improves code size in the vast majority of cases, we | |
507 | want to prevent any instructions using a "store post increment" from being | |
508 | generated. These will have to later be reloaded since msp430 does not | |
509 | support post inc for the destination operand. */ | |
510 | #define USE_STORE_POST_INCREMENT(MODE) 0 | |
511 | ||
512 | /* Many other targets set USE_LOAD_POST_INCREMENT to 0. For msp430-elf | |
513 | the benefit of disabling it is not clear. When looking at code size, on | |
514 | average, there is a slight advantage to leaving it enabled. */ | |
515 | ||
d30d00a2 NC |
516 | #undef ASM_DECLARE_FUNCTION_NAME |
517 | #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ | |
518 | msp430_start_function ((FILE), (NAME), (DECL)) | |
c6f709ec NC |
519 | |
520 | #define TARGET_HAS_NO_HW_DIVIDE (! TARGET_HWMULT) | |
d7edde11 | 521 | |
d7eabfd4 JL |
522 | void msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED, |
523 | const char *iprefix ATTRIBUTE_UNUSED, | |
524 | int stdinc ATTRIBUTE_UNUSED); | |
525 | #undef TARGET_EXTRA_PRE_INCLUDES | |
526 | #define TARGET_EXTRA_PRE_INCLUDES msp430_register_pre_includes | |
527 | ||
d7edde11 NC |
528 | #undef USE_SELECT_SECTION_FOR_FUNCTIONS |
529 | #define USE_SELECT_SECTION_FOR_FUNCTIONS 1 | |
530 | ||
e8fb1a38 | 531 | #undef ASM_OUTPUT_ALIGNED_DECL_COMMON |
d7edde11 | 532 | #define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN) \ |
e8fb1a38 JL |
533 | msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN), 0) |
534 | ||
535 | #undef ASM_OUTPUT_ALIGNED_DECL_LOCAL | |
536 | #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \ | |
537 | msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN), 1) | |
538 | ||
8682b1a5 JL |
539 | |
540 | #define SYMBOL_FLAG_LOW_MEM (SYMBOL_FLAG_MACH_DEP << 0) | |
546c8f95 JL |
541 | |
542 | #define ADJUST_INSN_LENGTH(insn, length) \ | |
543 | do \ | |
544 | { \ | |
545 | if (recog_memoized (insn) >= 0) \ | |
546 | { \ | |
547 | length += get_attr_extra_length (insn); \ | |
548 | length *= get_attr_length_multiplier (insn); \ | |
549 | } \ | |
550 | } while (0) |