1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2020 Free Software Foundation, Inc.
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
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 #define IN_TARGET_CODE 1
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "gimple-expr.h"
33 #include "df.h"
34 #include "memmodel.h"
35 #include "tm_p.h"
36 #include "regs.h"
37 #include "emit-rtl.h"
38 #include "varasm.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
42 #include "calls.h"
43 #include "output.h"
44 #include "explow.h"
45 #include "expr.h"
46 #include "langhooks.h"
47 #include "builtins.h"
48 #include "intl.h"
49 #include "msp430-devices.h"
50 #include "incpath.h"
51 #include "prefix.h"
52
53 /* This file should be included last. */
54 #include "target-def.h"
55
56
57 static void msp430_compute_frame_info (void);
58 static bool use_32bit_hwmult (void);
59
60
61
62 /* Run-time Target Specification. */
63
64 bool msp430x = true;
65
66 struct GTY(()) machine_function
67 {
68 /* If set, the rest of the fields have been computed. */
69 int computed;
70 /* Which registers need to be saved in the pro/epilogue. */
71 int need_to_save[FIRST_PSEUDO_REGISTER];
72
73 /* These fields describe the frame layout... */
74 /* arg pointer */
75 /* 2/4 bytes for saved PC */
76 int framesize_regs;
77 /* frame pointer */
78 int framesize_locals;
79 int framesize_outgoing;
80 /* stack pointer */
81 int framesize;
82
83 /* How much we adjust the stack when returning from an exception
84 handler. */
85 rtx eh_stack_adjust;
86 };
87
88 /* This is our init_machine_status, as set in
89 msp430_option_override. */
90 static struct machine_function *
msp430_init_machine_status(void)91 msp430_init_machine_status (void)
92 {
93 struct machine_function *m;
94
95 m = ggc_cleared_alloc<machine_function> ();
96
97 return m;
98 }
99
100 #undef TARGET_OPTION_OVERRIDE
101 #define TARGET_OPTION_OVERRIDE msp430_option_override
102
103 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
104 If a specific MCU has not been selected then return a generic symbol
105 instead. */
106
107 const char *
msp430_mcu_name(void)108 msp430_mcu_name (void)
109 {
110 if (target_mcu)
111 {
112 msp430_extract_mcu_data (target_mcu);
113 unsigned int i;
114 unsigned int start_upper;
115 unsigned int end_upper;
116 static char mcu_name[64];
117
118 /* The 'i' in the device name symbol for msp430i* devices must be lower
119 case, to match the expected symbol in msp430.h. */
120 if (strncmp (target_mcu, "msp430i", 7) == 0)
121 {
122 snprintf (mcu_name, sizeof (mcu_name) - 1, "__MSP430i%s__",
123 target_mcu + 7);
124 start_upper = 9;
125 }
126 else
127 {
128 snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu);
129 start_upper = 2;
130 }
131 end_upper = strlen (mcu_name) - 2;
132 for (i = start_upper; i < end_upper; i++)
133 mcu_name[i] = TOUPPER (mcu_name[i]);
134 return mcu_name;
135 }
136
137 return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
138 }
139
140 static const char *
hwmult_name(unsigned int val)141 hwmult_name (unsigned int val)
142 {
143 switch (val)
144 {
145 case 0: return "none";
146 case 1: return "16-bit";
147 case 2: return "16-bit";
148 case 4: return "32-bit";
149 case 8: return "32-bit (5xx)";
150 default: gcc_unreachable ();
151 }
152 }
153
154 static void
msp430_option_override(void)155 msp430_option_override (void)
156 {
157 /* The MSP430 architecture can safely dereference a NULL pointer. In fact,
158 there are memory mapped registers there. */
159 flag_delete_null_pointer_checks = 0;
160
161 init_machine_status = msp430_init_machine_status;
162
163 if (target_cpu)
164 {
165 /* gcc/common/config/msp430-common.c will have
166 already canonicalised the string in target_cpu. */
167 if (strcasecmp (target_cpu, "msp430x") == 0)
168 msp430x = true;
169 else /* target_cpu == "msp430" - already handled by the front end. */
170 msp430x = false;
171 }
172
173 if (target_mcu)
174 {
175 msp430_extract_mcu_data (target_mcu);
176
177 if (extracted_mcu_data.name != NULL)
178 {
179 bool xisa = extracted_mcu_data.revision >= 1;
180
181 if (msp430_warn_mcu)
182 {
183 if (target_cpu && msp430x != xisa)
184 warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
185 "is set to %s",
186 target_mcu, xisa ? "430X" : "430",
187 msp430x ? "430X" : "430");
188
189 if (extracted_mcu_data.hwmpy == 0
190 && msp430_hwmult_type != MSP430_HWMULT_AUTO
191 && msp430_hwmult_type != MSP430_HWMULT_NONE)
192 warning (0, "MCU %qs does not have hardware multiply "
193 "support, but %<-mhwmult%> is set to %s",
194 target_mcu,
195 msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit"
196 : msp430_hwmult_type == MSP430_HWMULT_LARGE
197 ? "32-bit" : "f5series");
198 else if (msp430_hwmult_type == MSP430_HWMULT_SMALL
199 && extracted_mcu_data.hwmpy != 1
200 && extracted_mcu_data.hwmpy != 2)
201 warning (0, "MCU %qs supports %s hardware multiply, "
202 "but %<-mhwmult%> is set to 16-bit",
203 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
204 else if (msp430_hwmult_type == MSP430_HWMULT_LARGE
205 && extracted_mcu_data.hwmpy != 4)
206 warning (0, "MCU %qs supports %s hardware multiply, "
207 "but %<-mhwmult%> is set to 32-bit",
208 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
209 else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES
210 && extracted_mcu_data.hwmpy != 8)
211 warning (0, "MCU %qs supports %s hardware multiply, "
212 "but %<-mhwmult%> is set to f5series",
213 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
214 }
215 msp430x = xisa;
216 }
217 else
218 {
219 if (msp430_hwmult_type == MSP430_HWMULT_AUTO)
220 {
221 if (msp430_warn_mcu)
222 {
223 if (target_cpu == NULL)
224 warning (0,
225 "Unrecognized MCU name %qs, assuming that it is "
226 "just a MSP430 with no hardware multiply.\n"
227 "Use the %<-mcpu%> and %<-mhwmult%> options to "
228 "set these explicitly.",
229 target_mcu);
230 else
231 warning (0,
232 "Unrecognized MCU name %qs, assuming that it "
233 "has no hardware multiply.\nUse the %<-mhwmult%> "
234 "option to set this explicitly.",
235 target_mcu);
236 }
237
238 msp430_hwmult_type = MSP430_HWMULT_NONE;
239 }
240 else if (target_cpu == NULL)
241 {
242 if (msp430_warn_mcu)
243 warning (0,
244 "Unrecognized MCU name %qs, assuming that it just "
245 "supports the MSP430 ISA.\nUse the %<-mcpu%> option "
246 "to set the ISA explicitly.",
247 target_mcu);
248
249 msp430x = false;
250 }
251 else if (msp430_warn_mcu)
252 warning (0, "Unrecognized MCU name %qs.", target_mcu);
253 }
254 }
255
256 /* The F5 series are all able to support the 430X ISA. */
257 if (target_cpu == NULL && target_mcu == NULL
258 && msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
259 msp430x = true;
260
261 if (TARGET_LARGE && !msp430x)
262 error ("%<-mlarge%> requires a 430X-compatible %<-mmcu=%>");
263
264 if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_EITHER)
265 error ("%<-mcode-region=either%> requires the large memory model "
266 "(%<-mlarge%>)");
267 else if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_UPPER)
268 error ("%<-mcode-region=upper%> requires the large memory model "
269 "(%<-mlarge%>)");
270
271 if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_EITHER)
272 error ("%<-mdata-region=either%> requires the large memory model "
273 "(%<-mlarge%>)");
274 else if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_UPPER)
275 error ("%<-mdata-region=upper%> requires the large memory model "
276 "(%<-mlarge%>)");
277
278 if (flag_exceptions || flag_non_call_exceptions
279 || flag_unwind_tables || flag_asynchronous_unwind_tables)
280 flag_omit_frame_pointer = false;
281 else
282 flag_omit_frame_pointer = true;
283
284 /* This is a hack to work around a problem with the newlib build
285 mechanism. Newlib always appends CFLAGS to the end of the GCC
286 command line and always sets -O2 in CFLAGS. Thus it is not
287 possible to build newlib with -Os enabled. Until now... */
288 if (TARGET_OPT_SPACE && optimize < 3)
289 optimize_size = 1;
290
291 #if !DEFAULT_USE_CXA_ATEXIT
292 /* For some configurations, we use atexit () instead of __cxa_atexit () by
293 default to save on code size and remove the declaration of __dso_handle
294 from the CRT library.
295 Configuring GCC with --enable-__cxa-atexit re-enables it by defining
296 DEFAULT_USE_CXA_ATEXIT to 1. */
297 if (flag_use_cxa_atexit)
298 error ("%<-fuse-cxa-atexit%> is not supported for msp430-elf");
299 #endif
300
301 #ifndef HAVE_NEWLIB_NANO_FORMATTED_IO
302 if (TARGET_TINY_PRINTF)
303 error ("GCC must be configured with %<--enable-newlib-nano-formatted-io%> "
304 "to use %<-mtiny-printf%>");
305 #endif
306 }
307
308 #undef TARGET_SCALAR_MODE_SUPPORTED_P
309 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
310
311 static bool
msp430_scalar_mode_supported_p(scalar_mode m)312 msp430_scalar_mode_supported_p (scalar_mode m)
313 {
314 if (m == PSImode && msp430x)
315 return true;
316 #if 0
317 if (m == TImode)
318 return true;
319 #endif
320 return default_scalar_mode_supported_p (m);
321 }
322
323
324
325 /* Storage Layout */
326
327 #undef TARGET_MS_BITFIELD_LAYOUT_P
328 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
329
330 bool
msp430_ms_bitfield_layout_p(const_tree record_type ATTRIBUTE_UNUSED)331 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
332 {
333 return false;
334 }
335
336
337
338 /* Register Usage */
339
340 #undef TARGET_HARD_REGNO_NREGS
341 #define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs
342
343 static unsigned int
msp430_hard_regno_nregs(unsigned int,machine_mode mode)344 msp430_hard_regno_nregs (unsigned int, machine_mode mode)
345 {
346 if (mode == PSImode && msp430x)
347 return 1;
348 if (mode == CPSImode && msp430x)
349 return 2;
350 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
351 / UNITS_PER_WORD);
352 }
353
354 /* subreg_get_info correctly handles PSImode registers, so defining
355 HARD_REGNO_NREGS_HAS_PADDING and HARD_REGNO_NREGS_WITH_PADDING
356 has no effect. */
357
358 #undef TARGET_HARD_REGNO_MODE_OK
359 #define TARGET_HARD_REGNO_MODE_OK msp430_hard_regno_mode_ok
360
361 static bool
msp430_hard_regno_mode_ok(unsigned int regno,machine_mode mode)362 msp430_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
363 {
364 return regno <= (ARG_POINTER_REGNUM
365 - (unsigned int) msp430_hard_regno_nregs (regno, mode));
366 }
367
368 #undef TARGET_MODES_TIEABLE_P
369 #define TARGET_MODES_TIEABLE_P msp430_modes_tieable_p
370
371 static bool
msp430_modes_tieable_p(machine_mode mode1,machine_mode mode2)372 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2)
373 {
374 if ((mode1 == PSImode || mode2 == SImode)
375 || (mode1 == SImode || mode2 == PSImode))
376 return false;
377
378 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
379 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
380 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
381 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
382 }
383
384 #undef TARGET_FRAME_POINTER_REQUIRED
385 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
386
387 static bool
msp430_frame_pointer_required(void)388 msp430_frame_pointer_required (void)
389 {
390 return false;
391 }
392
393 #undef TARGET_CAN_ELIMINATE
394 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
395
396 static bool
msp430_can_eliminate(const int from_reg ATTRIBUTE_UNUSED,const int to_reg ATTRIBUTE_UNUSED)397 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
398 const int to_reg ATTRIBUTE_UNUSED)
399 {
400 return true;
401 }
402
403 /* Implements INITIAL_ELIMINATION_OFFSET. */
404 int
msp430_initial_elimination_offset(int from,int to)405 msp430_initial_elimination_offset (int from, int to)
406 {
407 int rv = 0; /* As if arg to arg. */
408
409 msp430_compute_frame_info ();
410
411 switch (to)
412 {
413 case STACK_POINTER_REGNUM:
414 rv += cfun->machine->framesize_outgoing;
415 rv += cfun->machine->framesize_locals;
416 /* Fall through. */
417 case FRAME_POINTER_REGNUM:
418 rv += cfun->machine->framesize_regs;
419 /* Allow for the saved return address. */
420 rv += (TARGET_LARGE ? 4 : 2);
421 /* NB/ No need to allow for crtl->args.pretend_args_size.
422 GCC does that for us. */
423 break;
424 default:
425 gcc_unreachable ();
426 }
427
428 switch (from)
429 {
430 case FRAME_POINTER_REGNUM:
431 /* Allow for the fall through above. */
432 rv -= (TARGET_LARGE ? 4 : 2);
433 rv -= cfun->machine->framesize_regs;
434 case ARG_POINTER_REGNUM:
435 break;
436 default:
437 gcc_unreachable ();
438 }
439
440 return rv;
441 }
442
443 /* Named Address Space support */
444
445
446 /* Return the appropriate mode for a named address pointer. */
447 #undef TARGET_ADDR_SPACE_POINTER_MODE
448 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
449 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
450 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
451
452 static scalar_int_mode
msp430_addr_space_pointer_mode(addr_space_t addrspace)453 msp430_addr_space_pointer_mode (addr_space_t addrspace)
454 {
455 switch (addrspace)
456 {
457 default:
458 case ADDR_SPACE_GENERIC:
459 return Pmode;
460 case ADDR_SPACE_NEAR:
461 return HImode;
462 case ADDR_SPACE_FAR:
463 return PSImode;
464 }
465 }
466
467 /* Function pointers are stored in unwind_word sized
468 variables, so make sure that unwind_word is big enough. */
469 #undef TARGET_UNWIND_WORD_MODE
470 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
471
472 static scalar_int_mode
msp430_unwind_word_mode(void)473 msp430_unwind_word_mode (void)
474 {
475 /* This needs to match msp430_init_dwarf_reg_sizes_extra (below). */
476 return msp430x ? PSImode : HImode;
477 }
478
479 /* Determine if one named address space is a subset of another. */
480 #undef TARGET_ADDR_SPACE_SUBSET_P
481 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
482 static bool
msp430_addr_space_subset_p(addr_space_t subset,addr_space_t superset)483 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
484 {
485 if (subset == superset)
486 return true;
487 else
488 return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR);
489 }
490
491 #undef TARGET_ADDR_SPACE_CONVERT
492 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
493 /* Convert from one address space to another. */
494 static rtx
msp430_addr_space_convert(rtx op,tree from_type,tree to_type)495 msp430_addr_space_convert (rtx op, tree from_type, tree to_type)
496 {
497 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
498 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
499 rtx result;
500
501 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
502 {
503 /* This is unpredictable, as we're truncating off usable address
504 bits. */
505
506 if (CONSTANT_P (op))
507 return gen_rtx_CONST (HImode, op);
508
509 result = gen_reg_rtx (HImode);
510 emit_insn (gen_truncpsihi2 (result, op));
511 return result;
512 }
513 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
514 {
515 /* This always works. */
516
517 if (CONSTANT_P (op))
518 return gen_rtx_CONST (PSImode, op);
519
520 result = gen_reg_rtx (PSImode);
521 emit_insn (gen_zero_extendhipsi2 (result, op));
522 return result;
523 }
524 else
525 gcc_unreachable ();
526 }
527
528 /* Stack Layout and Calling Conventions. */
529
530 /* For each function, we list the gcc version and the TI version on
531 each line, where we're converting the function names. */
532 static char const * const special_convention_function_names[] =
533 {
534 "__muldi3", "__mspabi_mpyll",
535 "__udivdi3", "__mspabi_divull",
536 "__umoddi3", "__mspabi_remull",
537 "__divdi3", "__mspabi_divlli",
538 "__moddi3", "__mspabi_remlli",
539 "__mspabi_srall",
540 "__mspabi_srlll",
541 "__mspabi_sllll",
542 "__adddf3", "__mspabi_addd",
543 "__subdf3", "__mspabi_subd",
544 "__muldf3", "__mspabi_mpyd",
545 "__divdf3", "__mspabi_divd",
546 "__mspabi_cmpd",
547 NULL
548 };
549
550 /* TRUE if the function passed is a "speical" function. Special
551 functions pass two DImode parameters in registers. */
552 static bool
msp430_special_register_convention_p(const char * name)553 msp430_special_register_convention_p (const char *name)
554 {
555 int i;
556
557 for (i = 0; special_convention_function_names[i]; i++)
558 if (!strcmp (name, special_convention_function_names[i]))
559 return true;
560
561 return false;
562 }
563
564 #undef TARGET_FUNCTION_VALUE_REGNO_P
565 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
566
567 bool
msp430_function_value_regno_p(unsigned int regno)568 msp430_function_value_regno_p (unsigned int regno)
569 {
570 return regno == 12;
571 }
572
573
574 #undef TARGET_FUNCTION_VALUE
575 #define TARGET_FUNCTION_VALUE msp430_function_value
576
577 rtx
msp430_function_value(const_tree ret_type,const_tree fn_decl_or_type ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)578 msp430_function_value (const_tree ret_type,
579 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
580 bool outgoing ATTRIBUTE_UNUSED)
581 {
582 return gen_rtx_REG (TYPE_MODE (ret_type), 12);
583 }
584
585 #undef TARGET_LIBCALL_VALUE
586 #define TARGET_LIBCALL_VALUE msp430_libcall_value
587
588 rtx
msp430_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)589 msp430_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
590 {
591 return gen_rtx_REG (mode, 12);
592 }
593
594 /* Implements INIT_CUMULATIVE_ARGS. */
595 void
msp430_init_cumulative_args(CUMULATIVE_ARGS * ca,tree fntype ATTRIBUTE_UNUSED,rtx libname ATTRIBUTE_UNUSED,tree fndecl ATTRIBUTE_UNUSED,int n_named_args ATTRIBUTE_UNUSED)596 msp430_init_cumulative_args (CUMULATIVE_ARGS *ca,
597 tree fntype ATTRIBUTE_UNUSED,
598 rtx libname ATTRIBUTE_UNUSED,
599 tree fndecl ATTRIBUTE_UNUSED,
600 int n_named_args ATTRIBUTE_UNUSED)
601 {
602 const char *fname;
603 memset (ca, 0, sizeof(*ca));
604
605 ca->can_split = 1;
606
607 if (fndecl)
608 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
609 else if (libname)
610 fname = XSTR (libname, 0);
611 else
612 fname = NULL;
613
614 if (fname && msp430_special_register_convention_p (fname))
615 ca->special_p = 1;
616 }
617
618 /* Helper function for argument passing; this function is the common
619 code that determines where an argument will be passed. */
620 static void
msp430_evaluate_arg(cumulative_args_t cap,machine_mode mode,const_tree type ATTRIBUTE_UNUSED,bool named)621 msp430_evaluate_arg (cumulative_args_t cap,
622 machine_mode mode,
623 const_tree type ATTRIBUTE_UNUSED,
624 bool named)
625 {
626 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
627 int nregs = GET_MODE_SIZE (mode);
628 int i;
629
630 ca->reg_count = 0;
631 ca->mem_count = 0;
632
633 if (!named)
634 return;
635
636 if (mode == PSImode)
637 nregs = 1;
638 else
639 nregs = (nregs + 1) / 2;
640
641 if (ca->special_p)
642 {
643 /* Function is passed two DImode operands, in R8:R11 and
644 R12:15. */
645 ca->start_reg = 8;
646 ca->reg_count = 4;
647 return;
648 }
649
650 switch (nregs)
651 {
652 case 1:
653 for (i = 0; i < 4; i++)
654 if (!ca->reg_used[i])
655 {
656 ca->reg_count = 1;
657 ca->start_reg = CA_FIRST_REG + i;
658 return;
659 }
660 break;
661 case 2:
662 for (i = 0; i < 3; i++)
663 if (!ca->reg_used[i] && !ca->reg_used[i + 1])
664 {
665 ca->reg_count = 2;
666 ca->start_reg = CA_FIRST_REG + i;
667 return;
668 }
669 if (!ca->reg_used[3] && ca->can_split)
670 {
671 ca->reg_count = 1;
672 ca->mem_count = 2;
673 ca->start_reg = CA_FIRST_REG + 3;
674 return;
675 }
676 break;
677 case 3:
678 case 4:
679 ca->can_split = 0;
680 if (!ca->reg_used[0]
681 && !ca->reg_used[1]
682 && !ca->reg_used[2]
683 && !ca->reg_used[3])
684 {
685 ca->reg_count = 4;
686 ca->start_reg = CA_FIRST_REG;
687 return;
688 }
689 break;
690 }
691 }
692
693 #undef TARGET_PROMOTE_PROTOTYPES
694 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
695
696 bool
msp430_promote_prototypes(const_tree fntype ATTRIBUTE_UNUSED)697 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
698 {
699 return false;
700 }
701
702 #undef TARGET_FUNCTION_ARG
703 #define TARGET_FUNCTION_ARG msp430_function_arg
704
705 rtx
msp430_function_arg(cumulative_args_t cap,const function_arg_info & arg)706 msp430_function_arg (cumulative_args_t cap,
707 const function_arg_info &arg)
708 {
709 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
710
711 msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
712
713 if (ca->reg_count)
714 return gen_rtx_REG (arg.mode, ca->start_reg);
715
716 return 0;
717 }
718
719 #undef TARGET_ARG_PARTIAL_BYTES
720 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
721
722 int
msp430_arg_partial_bytes(cumulative_args_t cap,const function_arg_info & arg)723 msp430_arg_partial_bytes (cumulative_args_t cap, const function_arg_info &arg)
724 {
725 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
726
727 msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
728
729 if (ca->reg_count && ca->mem_count)
730 return ca->reg_count * UNITS_PER_WORD;
731
732 return 0;
733 }
734
735 #undef TARGET_PASS_BY_REFERENCE
736 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
737
738 static bool
msp430_pass_by_reference(cumulative_args_t,const function_arg_info & arg)739 msp430_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
740 {
741 return (arg.mode == BLKmode
742 || (arg.type && TREE_CODE (arg.type) == RECORD_TYPE)
743 || (arg.type && TREE_CODE (arg.type) == UNION_TYPE));
744 }
745
746 #undef TARGET_CALLEE_COPIES
747 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_arg_info_true
748
749 #undef TARGET_FUNCTION_ARG_ADVANCE
750 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
751
752 void
msp430_function_arg_advance(cumulative_args_t cap,const function_arg_info & arg)753 msp430_function_arg_advance (cumulative_args_t cap,
754 const function_arg_info &arg)
755 {
756 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
757 int i;
758
759 msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
760
761 if (ca->start_reg >= CA_FIRST_REG)
762 for (i = 0; i < ca->reg_count; i ++)
763 ca->reg_used[i + ca->start_reg - CA_FIRST_REG] = 1;
764
765 ca->special_p = 0;
766 }
767
768 #undef TARGET_FUNCTION_ARG_BOUNDARY
769 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
770
771 static unsigned int
msp430_function_arg_boundary(machine_mode mode,const_tree type)772 msp430_function_arg_boundary (machine_mode mode, const_tree type)
773 {
774 if (mode == BLKmode
775 && int_size_in_bytes (type) > 1)
776 return 16;
777 if (GET_MODE_BITSIZE (mode) > 8)
778 return 16;
779 return 8;
780 }
781
782 #undef TARGET_RETURN_IN_MEMORY
783 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
784
785 static bool
msp430_return_in_memory(const_tree ret_type,const_tree fntype ATTRIBUTE_UNUSED)786 msp430_return_in_memory (const_tree ret_type,
787 const_tree fntype ATTRIBUTE_UNUSED)
788 {
789 machine_mode mode = TYPE_MODE (ret_type);
790
791 if (mode == BLKmode
792 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE)
793 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE))
794 return true;
795
796 if (GET_MODE_SIZE (mode) > 8)
797 return true;
798
799 return false;
800 }
801
802 #undef TARGET_GET_RAW_ARG_MODE
803 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
804
805 static fixed_size_mode
msp430_get_raw_arg_mode(int regno)806 msp430_get_raw_arg_mode (int regno)
807 {
808 return as_a <fixed_size_mode> (regno == ARG_POINTER_REGNUM
809 ? VOIDmode : Pmode);
810 }
811
812 #undef TARGET_GET_RAW_RESULT_MODE
813 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
814
815 static fixed_size_mode
msp430_get_raw_result_mode(int regno ATTRIBUTE_UNUSED)816 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
817 {
818 return Pmode;
819 }
820
821 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
822 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
823
824 #include "gimplify.h"
825
826 static tree
msp430_gimplify_va_arg_expr(tree valist,tree type,gimple_seq * pre_p,gimple_seq * post_p)827 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
828 gimple_seq *post_p)
829 {
830 tree addr, t, type_size, rounded_size, valist_tmp;
831 unsigned HOST_WIDE_INT align, boundary;
832 bool indirect;
833
834 indirect = pass_va_arg_by_reference (type);
835 if (indirect)
836 type = build_pointer_type (type);
837
838 align = PARM_BOUNDARY / BITS_PER_UNIT;
839 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
840
841 /* When we align parameter on stack for caller, if the parameter
842 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
843 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
844 here with caller. */
845 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
846 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
847
848 boundary /= BITS_PER_UNIT;
849
850 /* Hoist the valist value into a temporary for the moment. */
851 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
852
853 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
854 requires greater alignment, we must perform dynamic alignment. */
855 if (boundary > align
856 && !integer_zerop (TYPE_SIZE (type)))
857 {
858 /* FIXME: This is where this function diverts from targhooks.c:
859 std_gimplify_va_arg_expr(). It works, but I do not know why... */
860 if (! POINTER_TYPE_P (type))
861 {
862 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
863 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
864 gimplify_and_add (t, pre_p);
865
866 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
867 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
868 valist_tmp,
869 build_int_cst (TREE_TYPE (valist),
870 -boundary)));
871 gimplify_and_add (t, pre_p);
872 }
873 }
874 else
875 boundary = align;
876
877 /* If the actual alignment is less than the alignment of the type,
878 adjust the type accordingly so that we don't assume strict alignment
879 when dereferencing the pointer. */
880 boundary *= BITS_PER_UNIT;
881 if (boundary < TYPE_ALIGN (type))
882 {
883 type = build_variant_type_copy (type);
884 SET_TYPE_ALIGN (type, boundary);
885 }
886
887 /* Compute the rounded size of the type. */
888 type_size = size_in_bytes (type);
889 rounded_size = round_up (type_size, align);
890
891 /* Reduce rounded_size so it's sharable with the postqueue. */
892 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
893
894 /* Get AP. */
895 addr = valist_tmp;
896
897 /* Compute new value for AP. */
898 t = fold_build_pointer_plus (valist_tmp, rounded_size);
899 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
900 gimplify_and_add (t, pre_p);
901
902 addr = fold_convert (build_pointer_type (type), addr);
903
904 if (indirect)
905 addr = build_va_arg_indirect_ref (addr);
906
907 addr = build_va_arg_indirect_ref (addr);
908
909 return addr;
910 }
911
912 #undef TARGET_LRA_P
913 #define TARGET_LRA_P hook_bool_void_false
914
915 /* Addressing Modes */
916
917 #undef TARGET_LEGITIMATE_ADDRESS_P
918 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
919
920 static bool
reg_ok_for_addr(rtx r,bool strict)921 reg_ok_for_addr (rtx r, bool strict)
922 {
923 int rn = REGNO (r);
924
925 if (strict && rn >= FIRST_PSEUDO_REGISTER)
926 rn = reg_renumber[rn];
927 if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
928 return true;
929 if (!strict)
930 return true;
931 return false;
932 }
933
934 bool
msp430_legitimate_address_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x ATTRIBUTE_UNUSED,bool strict ATTRIBUTE_UNUSED)935 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
936 rtx x ATTRIBUTE_UNUSED,
937 bool strict ATTRIBUTE_UNUSED)
938 {
939 switch (GET_CODE (x))
940 {
941 case MEM:
942 return false;
943
944 case PLUS:
945 case POST_INC:
946 if (REG_P (XEXP (x, 0)))
947 {
948 if (GET_MODE (x) != GET_MODE (XEXP (x, 0)))
949 return false;
950 if (!reg_ok_for_addr (XEXP (x, 0), strict))
951 return false;
952 if (GET_CODE (x) == POST_INC)
953 /* At this point, if the original rtx was a post_inc, we don't have
954 anything further to check. */
955 return true;
956 switch (GET_CODE (XEXP (x, 1)))
957 {
958 case CONST:
959 case SYMBOL_REF:
960 case CONST_INT:
961 return true;
962 default:
963 return false;
964 }
965 }
966 return false;
967
968 case REG:
969 if (!reg_ok_for_addr (x, strict))
970 return false;
971 /* FALLTHRU */
972 case CONST:
973 case SYMBOL_REF:
974 case CONST_INT:
975 return true;
976
977 default:
978 return false;
979 }
980 }
981
982 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
983 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
984 msp430_addr_space_legitimate_address_p
985
986 bool
msp430_addr_space_legitimate_address_p(machine_mode mode,rtx x,bool strict,addr_space_t as ATTRIBUTE_UNUSED)987 msp430_addr_space_legitimate_address_p (machine_mode mode,
988 rtx x,
989 bool strict,
990 addr_space_t as ATTRIBUTE_UNUSED)
991 {
992 return msp430_legitimate_address_p (mode, x, strict);
993 }
994
995 #undef TARGET_ASM_INTEGER
996 #define TARGET_ASM_INTEGER msp430_asm_integer
997 static bool
msp430_asm_integer(rtx x,unsigned int size,int aligned_p)998 msp430_asm_integer (rtx x, unsigned int size, int aligned_p)
999 {
1000 int c = GET_CODE (x);
1001
1002 if (size == 3 && GET_MODE (x) == PSImode)
1003 size = 4;
1004
1005 switch (size)
1006 {
1007 case 4:
1008 if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT
1009 || c == PLUS || c == MINUS)
1010 {
1011 fprintf (asm_out_file, "\t.long\t");
1012 output_addr_const (asm_out_file, x);
1013 fputc ('\n', asm_out_file);
1014 return true;
1015 }
1016 break;
1017 }
1018 return default_assemble_integer (x, size, aligned_p);
1019 }
1020
1021 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1022 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
1023 static bool
msp430_asm_output_addr_const_extra(FILE * file ATTRIBUTE_UNUSED,rtx x)1024 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
1025 {
1026 debug_rtx (x);
1027 return false;
1028 }
1029
1030 #undef TARGET_LEGITIMATE_CONSTANT_P
1031 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1032
1033 static bool
msp430_legitimate_constant(machine_mode mode,rtx x)1034 msp430_legitimate_constant (machine_mode mode, rtx x)
1035 {
1036 return ! CONST_INT_P (x)
1037 || mode != PSImode
1038 /* GCC does not know the width of the PSImode, so make
1039 sure that it does not try to use a constant value that
1040 is out of range. */
1041 || (INTVAL (x) < (1 << 20)
1042 && INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20));
1043 }
1044
1045
1046 #undef TARGET_RTX_COSTS
1047 #define TARGET_RTX_COSTS msp430_rtx_costs
1048
msp430_rtx_costs(rtx x ATTRIBUTE_UNUSED,machine_mode mode,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)1049 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED,
1050 machine_mode mode,
1051 int outer_code ATTRIBUTE_UNUSED,
1052 int opno ATTRIBUTE_UNUSED,
1053 int * total,
1054 bool speed ATTRIBUTE_UNUSED)
1055 {
1056 int code = GET_CODE (x);
1057
1058 switch (code)
1059 {
1060 case SIGN_EXTEND:
1061 if (mode == SImode && outer_code == SET)
1062 {
1063 *total = COSTS_N_INSNS (4);
1064 return true;
1065 }
1066 break;
1067 case ASHIFT:
1068 case ASHIFTRT:
1069 case LSHIFTRT:
1070 if (!msp430x)
1071 {
1072 *total = COSTS_N_INSNS (100);
1073 return true;
1074 }
1075 break;
1076 }
1077 return false;
1078 }
1079
1080 /* Function Entry and Exit */
1081
1082 /* The MSP430 call frame looks like this:
1083
1084 <higher addresses>
1085 +--------------------+
1086 | |
1087 | Stack Arguments |
1088 | |
1089 +--------------------+ <-- "arg pointer"
1090 | |
1091 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1092 | |
1093 +--------------------+
1094 | SR if this func has|
1095 | been called via an |
1096 | interrupt. |
1097 +--------------------+ <-- SP before prologue, also AP
1098 | |
1099 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1100 | |
1101 +--------------------+ <-- "frame pointer"
1102 | |
1103 | Locals |
1104 | |
1105 +--------------------+
1106 | |
1107 | Outgoing Args |
1108 | |
1109 +--------------------+ <-- SP during function
1110 <lower addresses>
1111
1112 */
1113
1114 /* We use this to wrap all emitted insns in the prologue, so they get
1115 the "frame-related" (/f) flag set. */
1116 static rtx
F(rtx x)1117 F (rtx x)
1118 {
1119 RTX_FRAME_RELATED_P (x) = 1;
1120 return x;
1121 }
1122
1123 /* This is the one spot that decides if a register is to be saved and
1124 restored in the prologue/epilogue. */
1125 static bool
msp430_preserve_reg_p(int regno)1126 msp430_preserve_reg_p (int regno)
1127 {
1128 /* PC, SP, SR, and the constant generator. */
1129 if (regno <= 3)
1130 return false;
1131
1132 /* FIXME: add interrupt, EH, etc. */
1133 if (crtl->calls_eh_return)
1134 return true;
1135
1136 /* Shouldn't be more than the above, but just in case... */
1137 if (fixed_regs[regno])
1138 return false;
1139
1140 /* For interrupt functions we must save and restore the used regs that
1141 would normally be caller-saved (R11->R15). */
1142 if (msp430_is_interrupt_func () && regno >= 11 && regno <= 15)
1143 {
1144 if (crtl->is_leaf && df_regs_ever_live_p (regno))
1145 /* If the interrupt func is a leaf then we only need to restore the
1146 caller-saved regs that are used. */
1147 return true;
1148 else if (!crtl->is_leaf)
1149 /* If the interrupt function is not a leaf we must save all
1150 caller-saved regs in case the callee modifies them. */
1151 return true;
1152 }
1153
1154 if (!call_used_or_fixed_reg_p (regno)
1155 && df_regs_ever_live_p (regno))
1156 return true;
1157
1158 return false;
1159 }
1160
1161 /* Compute all the frame-related fields in our machine_function
1162 structure. */
1163 static void
msp430_compute_frame_info(void)1164 msp430_compute_frame_info (void)
1165 {
1166 int i;
1167
1168 cfun->machine->computed = 1;
1169 cfun->machine->framesize_regs = 0;
1170 cfun->machine->framesize_locals = get_frame_size ();
1171 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
1172
1173 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1174 if (msp430_preserve_reg_p (i))
1175 {
1176 cfun->machine->need_to_save[i] = 1;
1177 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1178 }
1179 else
1180 cfun->machine->need_to_save[i] = 0;
1181
1182 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1183 cfun->machine->framesize_locals ++;
1184
1185 cfun->machine->framesize = (cfun->machine->framesize_regs
1186 + cfun->machine->framesize_locals
1187 + cfun->machine->framesize_outgoing);
1188 }
1189
1190 /* Attribute Handling. */
1191
1192 const char * const ATTR_INTR = "interrupt";
1193 const char * const ATTR_WAKEUP = "wakeup";
1194 const char * const ATTR_NAKED = "naked";
1195 const char * const ATTR_REENT = "reentrant";
1196 const char * const ATTR_CRIT = "critical";
1197 const char * const ATTR_LOWER = "lower";
1198 const char * const ATTR_UPPER = "upper";
1199 const char * const ATTR_EITHER = "either";
1200 const char * const ATTR_NOINIT = "noinit";
1201 const char * const ATTR_PERSIST = "persistent";
1202
1203 static inline bool
has_attr(const char * attr,tree decl)1204 has_attr (const char * attr, tree decl)
1205 {
1206 if (decl == NULL_TREE)
1207 return false;
1208 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1209 }
1210
1211 static bool
1212 is_interrupt_func (tree decl = current_function_decl)
1213 {
1214 return has_attr (ATTR_INTR, decl);
1215 }
1216
1217 /* Returns true if the current function has the "interrupt" attribute. */
1218
1219 bool
msp430_is_interrupt_func(void)1220 msp430_is_interrupt_func (void)
1221 {
1222 return is_interrupt_func (current_function_decl);
1223 }
1224
1225 static bool
1226 is_wakeup_func (tree decl = current_function_decl)
1227 {
1228 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1229 }
1230
1231 static inline bool
1232 is_naked_func (tree decl = current_function_decl)
1233 {
1234 return has_attr (ATTR_NAKED, decl);
1235 }
1236
1237 static inline bool
1238 is_reentrant_func (tree decl = current_function_decl)
1239 {
1240 return has_attr (ATTR_REENT, decl);
1241 }
1242
1243 static inline bool
1244 is_critical_func (tree decl = current_function_decl)
1245 {
1246 return has_attr (ATTR_CRIT, decl);
1247 }
1248
1249 static bool
1250 has_section_name (const char * name, tree decl = current_function_decl)
1251 {
1252 if (decl == NULL_TREE)
1253 return false;
1254 return (DECL_SECTION_NAME (decl)
1255 && (strcmp (name, DECL_SECTION_NAME (decl)) == 0));
1256 }
1257
1258 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1259 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
1260 msp430_allocate_stack_slots_for_args
1261
1262 static bool
msp430_allocate_stack_slots_for_args(void)1263 msp430_allocate_stack_slots_for_args (void)
1264 {
1265 /* Naked functions should not allocate stack slots for arguments. */
1266 return ! is_naked_func ();
1267 }
1268
1269 #undef TARGET_WARN_FUNC_RETURN
1270 #define TARGET_WARN_FUNC_RETURN msp430_warn_func_return
1271
1272 static bool
msp430_warn_func_return(tree decl)1273 msp430_warn_func_return (tree decl)
1274 {
1275 /* Naked functions are implemented entirely in assembly, including the
1276 return sequence, so suppress warnings about this. */
1277 return !is_naked_func (decl);
1278 }
1279
1280 /* Verify MSP430 specific attributes. */
1281 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1282
1283 static tree
msp430_attr(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)1284 msp430_attr (tree * node,
1285 tree name,
1286 tree args,
1287 int flags ATTRIBUTE_UNUSED,
1288 bool * no_add_attrs)
1289 {
1290 gcc_assert (DECL_P (* node));
1291
1292 /* Only the interrupt attribute takes an argument. */
1293 if (args != NULL)
1294 {
1295 tree value = TREE_VALUE (args);
1296
1297 switch (TREE_CODE (value))
1298 {
1299 case STRING_CST:
1300 if ( strcmp (TREE_STRING_POINTER (value), "reset")
1301 && strcmp (TREE_STRING_POINTER (value), "nmi")
1302 && strcmp (TREE_STRING_POINTER (value), "watchdog"))
1303 /* Allow the attribute to be added - the linker script
1304 being used may still recognise this name. */
1305 warning (OPT_Wattributes,
1306 "unrecognized interrupt vector argument of %qE attribute",
1307 name);
1308 break;
1309
1310 case INTEGER_CST:
1311 if (wi::gtu_p (wi::to_wide (value), 63))
1312 /* Allow the attribute to be added - the linker script
1313 being used may still recognise this value. */
1314 warning (OPT_Wattributes,
1315 "numeric argument of %qE attribute must be in range 0..63",
1316 name);
1317 break;
1318
1319 default:
1320 warning (OPT_Wattributes,
1321 "argument of %qE attribute is not a string constant "
1322 "or number", name);
1323 *no_add_attrs = true;
1324 break;
1325 }
1326 }
1327
1328 const char * message = NULL;
1329
1330 if (TREE_CODE (* node) != FUNCTION_DECL)
1331 {
1332 message = "%qE attribute only applies to functions";
1333 }
1334 else if (TREE_NAME_EQ (name, ATTR_INTR))
1335 {
1336 if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE
1337 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node))))
1338 message = "interrupt handlers must be void";
1339 else
1340 {
1341 /* Ensure interrupt handlers never get optimised out. */
1342 TREE_USED (* node) = 1;
1343 DECL_PRESERVE_P (* node) = 1;
1344 }
1345 if (is_critical_func (* node))
1346 {
1347 /* We always ignore the critical attribute when interrupt and
1348 critical are used together. */
1349 warning (OPT_Wattributes,
1350 "critical attribute has no effect on interrupt functions");
1351 DECL_ATTRIBUTES (*node) = remove_attribute (ATTR_CRIT,
1352 DECL_ATTRIBUTES (* node));
1353 }
1354 }
1355 else if (TREE_NAME_EQ (name, ATTR_CRIT))
1356 {
1357 if (is_interrupt_func ( *node))
1358 message = "critical attribute has no effect on interrupt functions";
1359 }
1360
1361 if (message)
1362 {
1363 warning (OPT_Wattributes, message, name);
1364 * no_add_attrs = true;
1365 }
1366
1367 return NULL_TREE;
1368 }
1369
1370 static tree
msp430_section_attr(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs ATTRIBUTE_UNUSED)1371 msp430_section_attr (tree * node,
1372 tree name,
1373 tree args,
1374 int flags ATTRIBUTE_UNUSED,
1375 bool * no_add_attrs ATTRIBUTE_UNUSED)
1376 {
1377 gcc_assert (DECL_P (* node));
1378 gcc_assert (args == NULL);
1379
1380 const char * message = NULL;
1381
1382 /* The "noinit" and "section" attributes are handled generically, so we
1383 cannot set up additional target-specific attribute exclusions using the
1384 existing mechanism. */
1385 if (has_attr (ATTR_NOINIT, *node))
1386 message = G_("ignoring attribute %qE because it conflicts with "
1387 "attribute %<noinit%>");
1388 else if (has_attr ("section", *node) && !TREE_NAME_EQ (name, "lower"))
1389 message = G_("ignoring attribute %qE because it conflicts with "
1390 "attribute %<section%>");
1391 /* It does not make sense to use upper/lower/either attributes without
1392 -mlarge.
1393 Without -mlarge, "lower" is the default and only region, so is redundant.
1394 Without -mlarge, "upper" will (and "either" might) place code/data in the
1395 upper region, which for data could result in relocation overflows, and for
1396 code could result in stack mismanagement and incorrect call/return
1397 instructions. */
1398 else if (!TARGET_LARGE)
1399 message = G_("%qE attribute ignored. Large memory model (%<-mlarge%>) "
1400 "is required.");
1401
1402 if (message)
1403 {
1404 warning (OPT_Wattributes, message, name);
1405 * no_add_attrs = true;
1406 }
1407
1408 return NULL_TREE;
1409 }
1410
1411 static tree
msp430_persist_attr(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs ATTRIBUTE_UNUSED)1412 msp430_persist_attr (tree *node,
1413 tree name,
1414 tree args,
1415 int flags ATTRIBUTE_UNUSED,
1416 bool * no_add_attrs ATTRIBUTE_UNUSED)
1417 {
1418 const char * message = NULL;
1419
1420 gcc_assert (DECL_P (* node));
1421 gcc_assert (args == NULL);
1422 gcc_assert (TREE_NAME_EQ (name, ATTR_PERSIST));
1423
1424 /* Check for the section attribute separately from DECL_SECTION_NAME so
1425 we can provide a clearer warning. */
1426 if (has_attr ("section", *node))
1427 message = G_("ignoring attribute %qE because it conflicts with "
1428 "attribute %<section%>");
1429 /* Check that it's possible for the variable to have a section. */
1430 else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p)
1431 && (DECL_SECTION_NAME (*node)))
1432 message = G_("%qE attribute cannot be applied to variables with specific "
1433 "sections");
1434 else if (has_attr (ATTR_NOINIT, *node))
1435 message = G_("ignoring attribute %qE because it conflicts with "
1436 "attribute %<noinit%>");
1437 else if (TREE_CODE (*node) != VAR_DECL)
1438 message = G_("%qE attribute only applies to variables");
1439 else if (!TREE_STATIC (*node) && !TREE_PUBLIC (*node)
1440 && !DECL_EXTERNAL (*node))
1441 message = G_("%qE attribute has no effect on automatic variables");
1442 else if (DECL_COMMON (*node) || DECL_INITIAL (*node) == NULL)
1443 message = G_("variables marked with %qE attribute must be initialized");
1444 else
1445 /* It's not clear if there is anything that can be set here to prevent the
1446 front end placing the variable before the back end can handle it, in a
1447 similar way to how DECL_COMMON is cleared for .noinit variables in
1448 handle_noinit_attribute (gcc/c-family/c-attribs.c).
1449 So just place the variable in the .persistent section now. */
1450 set_decl_section_name (* node, ".persistent");
1451
1452 if (message)
1453 {
1454 warning (OPT_Wattributes, message, name);
1455 * no_add_attrs = true;
1456 }
1457
1458 return NULL_TREE;
1459 }
1460
1461 /* Helper to define attribute exclusions. */
1462 #define ATTR_EXCL(name, function, type, variable) \
1463 { name, function, type, variable }
1464
1465 /* "reentrant", "critical" and "naked" functions must conflict because
1466 they all modify the prologue or epilogue of functions in mutually exclusive
1467 ways. */
1468 static const struct attribute_spec::exclusions attr_reent_exclusions[] =
1469 {
1470 ATTR_EXCL (ATTR_NAKED, true, true, true),
1471 ATTR_EXCL (ATTR_CRIT, true, true, true),
1472 ATTR_EXCL (NULL, false, false, false)
1473 };
1474
1475 static const struct attribute_spec::exclusions attr_naked_exclusions[] =
1476 {
1477 ATTR_EXCL (ATTR_REENT, true, true, true),
1478 ATTR_EXCL (ATTR_CRIT, true, true, true),
1479 ATTR_EXCL (NULL, false, false, false)
1480 };
1481
1482 static const struct attribute_spec::exclusions attr_crit_exclusions[] =
1483 {
1484 ATTR_EXCL (ATTR_REENT, true, true, true),
1485 ATTR_EXCL (ATTR_NAKED, true, true, true),
1486 ATTR_EXCL (NULL, false, false, false)
1487 };
1488
1489 /* Attributes which put the given object in a specific section must conflict
1490 with one another. */
1491 static const struct attribute_spec::exclusions attr_lower_exclusions[] =
1492 {
1493 ATTR_EXCL (ATTR_UPPER, true, true, true),
1494 ATTR_EXCL (ATTR_EITHER, true, true, true),
1495 ATTR_EXCL (ATTR_PERSIST, true, true, true),
1496 ATTR_EXCL (NULL, false, false, false)
1497 };
1498
1499 static const struct attribute_spec::exclusions attr_upper_exclusions[] =
1500 {
1501 ATTR_EXCL (ATTR_LOWER, true, true, true),
1502 ATTR_EXCL (ATTR_EITHER, true, true, true),
1503 ATTR_EXCL (ATTR_PERSIST, true, true, true),
1504 ATTR_EXCL (NULL, false, false, false)
1505 };
1506
1507 static const struct attribute_spec::exclusions attr_either_exclusions[] =
1508 {
1509 ATTR_EXCL (ATTR_LOWER, true, true, true),
1510 ATTR_EXCL (ATTR_UPPER, true, true, true),
1511 ATTR_EXCL (ATTR_PERSIST, true, true, true),
1512 ATTR_EXCL (NULL, false, false, false)
1513 };
1514
1515 static const struct attribute_spec::exclusions attr_persist_exclusions[] =
1516 {
1517 ATTR_EXCL (ATTR_LOWER, true, true, true),
1518 ATTR_EXCL (ATTR_UPPER, true, true, true),
1519 ATTR_EXCL (ATTR_EITHER, true, true, true),
1520 ATTR_EXCL (NULL, false, false, false)
1521 };
1522
1523 #undef TARGET_ATTRIBUTE_TABLE
1524 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1525
1526 /* Table of MSP430-specific attributes. */
1527 const struct attribute_spec msp430_attribute_table[] =
1528 {
1529 /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
1530 affects_type_identity, handler, exclude } */
1531 { ATTR_INTR, 0, 1, true, false, false, false, msp430_attr, NULL },
1532 { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr,
1533 attr_naked_exclusions },
1534 { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr,
1535 attr_reent_exclusions },
1536 { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr,
1537 attr_crit_exclusions },
1538 { ATTR_WAKEUP, 0, 0, true, false, false, false, msp430_attr, NULL },
1539
1540 { ATTR_LOWER, 0, 0, true, false, false, false, msp430_section_attr,
1541 attr_lower_exclusions },
1542 { ATTR_UPPER, 0, 0, true, false, false, false, msp430_section_attr,
1543 attr_upper_exclusions },
1544 { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr,
1545 attr_either_exclusions },
1546
1547 { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_persist_attr,
1548 attr_persist_exclusions },
1549
1550 { NULL, 0, 0, false, false, false, false, NULL, NULL }
1551 };
1552
1553 #undef TARGET_HANDLE_GENERIC_ATTRIBUTE
1554 #define TARGET_HANDLE_GENERIC_ATTRIBUTE msp430_handle_generic_attribute
1555
1556 tree
msp430_handle_generic_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)1557 msp430_handle_generic_attribute (tree *node,
1558 tree name,
1559 tree args ATTRIBUTE_UNUSED,
1560 int flags ATTRIBUTE_UNUSED,
1561 bool *no_add_attrs)
1562
1563 {
1564 const char *message = NULL;
1565
1566 /* The front end has set up an exclusion between the "noinit" and "section"
1567 attributes. */
1568 if (!(TREE_NAME_EQ (name, ATTR_NOINIT) || TREE_NAME_EQ (name, "section")))
1569 return NULL_TREE;
1570
1571 /* We allow the "lower" attribute to be used on variables with the "section"
1572 attribute. */
1573 if (has_attr (ATTR_LOWER, *node) && !TREE_NAME_EQ (name, "section"))
1574 message = G_("ignoring attribute %qE because it conflicts with "
1575 "attribute %<lower%>");
1576 else if (has_attr (ATTR_UPPER, *node))
1577 message = G_("ignoring attribute %qE because it conflicts with "
1578 "attribute %<upper%>");
1579 else if (has_attr (ATTR_EITHER, *node))
1580 message = G_("ignoring attribute %qE because it conflicts with "
1581 "attribute %<either%>");
1582 else if (has_attr (ATTR_PERSIST, *node))
1583 message = G_("ignoring attribute %qE because it conflicts with "
1584 "attribute %<persistent%>");
1585
1586 if (message)
1587 {
1588 warning (OPT_Wattributes, message, name);
1589 *no_add_attrs = true;
1590 }
1591
1592 return NULL_TREE;
1593 }
1594
1595 /* Given a non-automatic VAR_DECL which can possibly have a section, return
1596 true if the variable will definitely be placed in the lower memory
1597 region (below address 0x10000). */
1598 static bool
msp430_var_in_low_mem(tree decl)1599 msp430_var_in_low_mem (tree decl)
1600 {
1601 gcc_assert (VAR_P (decl));
1602
1603 /* "noinit" variables are always placed in the lower memory region. */
1604 if (has_attr (ATTR_UPPER, decl)
1605 || has_attr (ATTR_EITHER, decl)
1606 || has_attr (ATTR_PERSIST, decl)
1607 /* Unless the variable is marked with the lower or noinit attribute, we
1608 cannot assume that it is in the lower region if it is marked with the
1609 section attribute or -mdata-region={upper,either,none} have been
1610 passed.
1611 The noinit and section attributes conflict. */
1612 || (!has_attr (ATTR_LOWER, decl) && !has_attr (ATTR_NOINIT, decl)
1613 && (has_attr ("section", decl)
1614 || msp430_data_region == MSP430_REGION_UPPER
1615 || msp430_data_region == MSP430_REGION_EITHER
1616 || msp430_data_region == MSP430_REGION_ANY)))
1617 return false;
1618 return true;
1619 }
1620
1621 #undef TARGET_ENCODE_SECTION_INFO
1622 #define TARGET_ENCODE_SECTION_INFO msp430_encode_section_info
1623
1624 /* Encode whether a SYMBOL_REF is definitely in the lower memory region. */
1625 static void
msp430_encode_section_info(tree decl,rtx rtl,int first)1626 msp430_encode_section_info (tree decl, rtx rtl, int first)
1627 {
1628 rtx symbol;
1629 default_encode_section_info (decl, rtl, first);
1630
1631 /* Careful not to prod global register variables. */
1632 if (!MEM_P (rtl))
1633 return;
1634 symbol = XEXP (rtl, 0);
1635 if (GET_CODE (symbol) != SYMBOL_REF)
1636 return;
1637
1638 if (VAR_P (decl)
1639 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1640 && msp430_var_in_low_mem (decl))
1641 SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOW_MEM;
1642 }
1643
1644 #undef TARGET_ASM_FUNCTION_PROLOGUE
1645 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1646
1647 static void
msp430_start_function(FILE * outfile)1648 msp430_start_function (FILE *outfile)
1649 {
1650 int r, n;
1651
1652 fprintf (outfile, "; start of function\n");
1653
1654 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
1655 {
1656 fprintf (outfile, "; attributes: ");
1657 if (is_naked_func ())
1658 fprintf (outfile, "naked ");
1659 if (msp430_is_interrupt_func ())
1660 fprintf (outfile, "interrupt ");
1661 if (is_reentrant_func ())
1662 fprintf (outfile, "reentrant ");
1663 if (is_critical_func ())
1664 fprintf (outfile, "critical ");
1665 if (is_wakeup_func ())
1666 fprintf (outfile, "wakeup ");
1667 fprintf (outfile, "\n");
1668 }
1669
1670 fprintf (outfile, "; framesize_regs: %d\n",
1671 cfun->machine->framesize_regs);
1672 fprintf (outfile, "; framesize_locals: %d\n",
1673 cfun->machine->framesize_locals);
1674 fprintf (outfile, "; framesize_outgoing: %d\n",
1675 cfun->machine->framesize_outgoing);
1676 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
1677 fprintf (outfile, "; elim ap -> fp %d\n",
1678 msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
1679 FRAME_POINTER_REGNUM));
1680 fprintf (outfile, "; elim fp -> sp %d\n",
1681 msp430_initial_elimination_offset (FRAME_POINTER_REGNUM,
1682 STACK_POINTER_REGNUM));
1683
1684 n = 0;
1685 fprintf (outfile, "; saved regs:");
1686 for (r = 0; r < ARG_POINTER_REGNUM; r++)
1687 if (cfun->machine->need_to_save[r])
1688 {
1689 fprintf (outfile, " %s", reg_names[r]);
1690 n = 1;
1691 }
1692 if (n == 0)
1693 fprintf (outfile, "(none)");
1694 fprintf (outfile, "\n");
1695 }
1696
1697 /* Common code to change the stack pointer. */
1698 static void
increment_stack(HOST_WIDE_INT amount)1699 increment_stack (HOST_WIDE_INT amount)
1700 {
1701 rtx inc;
1702 rtx sp = stack_pointer_rtx;
1703
1704 if (amount == 0)
1705 return;
1706
1707 if (amount < 0)
1708 {
1709 inc = GEN_INT (- amount);
1710 if (TARGET_LARGE)
1711 F (emit_insn (gen_subpsi3 (sp, sp, inc)));
1712 else
1713 F (emit_insn (gen_subhi3 (sp, sp, inc)));
1714 }
1715 else
1716 {
1717 inc = GEN_INT (amount);
1718 if (TARGET_LARGE)
1719 emit_insn (gen_addpsi3 (sp, sp, inc));
1720 else
1721 emit_insn (gen_addhi3 (sp, sp, inc));
1722 }
1723 }
1724
1725 void
msp430_start_function(FILE * file,const char * name,tree decl)1726 msp430_start_function (FILE *file, const char *name, tree decl)
1727 {
1728 tree int_attr;
1729
1730 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1731 if (int_attr != NULL_TREE)
1732 {
1733 tree intr_vector = TREE_VALUE (int_attr);
1734
1735 if (intr_vector != NULL_TREE)
1736 {
1737 char buf[101];
1738
1739 /* Interrupt vector sections should be unique, but use of weak
1740 functions implies multiple definitions. */
1741 if (DECL_WEAK (decl))
1742 {
1743 error ("argument to interrupt attribute is unsupported for weak "
1744 "functions");
1745 }
1746
1747 intr_vector = TREE_VALUE (intr_vector);
1748
1749 /* The interrupt attribute has a vector value. Turn this into a
1750 section name, switch to that section and put the address of
1751 the current function into that vector slot. Note msp430_attr()
1752 has already verified the vector name for us. */
1753 if (TREE_CODE (intr_vector) == STRING_CST)
1754 sprintf (buf, "__interrupt_vector_%.80s",
1755 TREE_STRING_POINTER (intr_vector));
1756 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1757 sprintf (buf, "__interrupt_vector_%u",
1758 (unsigned int) TREE_INT_CST_LOW (intr_vector));
1759
1760 switch_to_section (get_section (buf, SECTION_CODE, decl));
1761 fputs ("\t.word\t", file);
1762 assemble_name (file, name);
1763 fputc ('\n', file);
1764 fputc ('\t', file);
1765 }
1766 }
1767
1768 switch_to_section (function_section (decl));
1769 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
1770 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1771 }
1772
1773 static const char * const lower_prefix = ".lower";
1774 static const char * const upper_prefix = ".upper";
1775 static const char * const either_prefix = ".either";
1776
1777 /* Generate a prefix for a section name, based upon
1778 the region into which the object should be placed. */
1779
1780 static const char *
gen_prefix(tree decl)1781 gen_prefix (tree decl)
1782 {
1783 if (DECL_ONE_ONLY (decl))
1784 return NULL;
1785
1786 /* If the user has specified a particular section then do not use any
1787 prefix. */
1788 if (has_attr ("section", decl))
1789 return NULL;
1790
1791 /* If the function has been put in the .lowtext section (because it is an
1792 interrupt handler, and the large memory model is used), then do not add
1793 any prefixes. */
1794 if (has_section_name (".lowtext", decl))
1795 return NULL;
1796
1797 /* Memory regions require the large memory model. */
1798 if (!TARGET_LARGE)
1799 return NULL;
1800
1801 /* Note that we always apply the lower prefix when the attribute has been
1802 used. But we only apply the lower prefix when the lower region has been
1803 specified by a command line option if -muse-lower-region-prefix has also
1804 been passed. */
1805 if (has_attr (ATTR_LOWER, decl))
1806 return lower_prefix;
1807
1808 if (has_attr (ATTR_UPPER, decl))
1809 return upper_prefix;
1810
1811 if (has_attr (ATTR_EITHER, decl))
1812 return either_prefix;
1813
1814 if (TREE_CODE (decl) == FUNCTION_DECL)
1815 {
1816 if ((msp430_code_region == MSP430_REGION_LOWER)
1817 && TARGET_USE_LOWER_REGION_PREFIX)
1818 return lower_prefix;
1819
1820 if (msp430_code_region == MSP430_REGION_UPPER)
1821 return upper_prefix;
1822
1823 if (msp430_code_region == MSP430_REGION_EITHER)
1824 return either_prefix;
1825 }
1826 else
1827 {
1828 if ((msp430_data_region == MSP430_REGION_LOWER)
1829 && TARGET_USE_LOWER_REGION_PREFIX)
1830 return lower_prefix;
1831
1832 if (msp430_data_region == MSP430_REGION_UPPER)
1833 return upper_prefix;
1834
1835 if (msp430_data_region == MSP430_REGION_EITHER)
1836 return either_prefix;
1837 }
1838
1839 return NULL;
1840 }
1841
1842 static section * persist_section;
1843
1844 #undef TARGET_ASM_INIT_SECTIONS
1845 #define TARGET_ASM_INIT_SECTIONS msp430_init_sections
1846
1847 static void
msp430_init_sections(void)1848 msp430_init_sections (void)
1849 {
1850 persist_section = get_unnamed_section (0, output_section_asm_op,
1851 ".section .persistent,\"aw\"");
1852 }
1853
1854 #undef TARGET_ASM_SELECT_SECTION
1855 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1856
1857 static section *
msp430_select_section(tree decl,int reloc,unsigned HOST_WIDE_INT align)1858 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
1859 {
1860 const char *prefix;
1861 const char *sec_name;
1862 const char *base_sec_name;
1863
1864 gcc_assert (decl != NULL_TREE);
1865
1866 if (TREE_CODE (decl) == STRING_CST
1867 || TREE_CODE (decl) == CONSTRUCTOR
1868 || TREE_CODE (decl) == INTEGER_CST
1869 || TREE_CODE (decl) == VECTOR_CST
1870 || TREE_CODE (decl) == COMPLEX_CST)
1871 return default_select_section (decl, reloc, align);
1872
1873 /* In large mode we must make sure that interrupt handlers are put into
1874 low memory as the vector table only accepts 16-bit addresses. */
1875 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
1876 && is_interrupt_func (decl))
1877 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
1878
1879 if (has_attr (ATTR_PERSIST, decl))
1880 return persist_section;
1881
1882 /* ATTR_NOINIT is handled generically. */
1883 if (has_attr (ATTR_NOINIT, decl))
1884 return default_elf_select_section (decl, reloc, align);
1885
1886 prefix = gen_prefix (decl);
1887
1888 switch (categorize_decl_for_section (decl, reloc))
1889 {
1890 case SECCAT_TEXT:
1891 if (!prefix)
1892 return text_section;
1893 base_sec_name = ".text";
1894 break;
1895 case SECCAT_DATA:
1896 if (!prefix)
1897 return data_section;
1898 base_sec_name = ".data";
1899 break;
1900 case SECCAT_BSS:
1901 if (!prefix)
1902 return bss_section;
1903 base_sec_name = ".bss";
1904 break;
1905 case SECCAT_RODATA:
1906 if (!prefix)
1907 return readonly_data_section;
1908 base_sec_name = ".rodata";
1909 break;
1910
1911 /* Enable merging of constant data by the GNU linker using
1912 default_elf_select_section and therefore enabling creation of
1913 sections with the SHF_MERGE flag. */
1914 case SECCAT_RODATA_MERGE_STR:
1915 case SECCAT_RODATA_MERGE_STR_INIT:
1916 case SECCAT_RODATA_MERGE_CONST:
1917 return default_elf_select_section (decl, reloc, align);
1918
1919 /* The sections listed below are not supported for MSP430.
1920 They should not be generated, but in case they are, we use
1921 default_select_section so they get placed in sections
1922 the msp430 assembler and linker understand. */
1923 /* "small data" sections are not supported. */
1924 case SECCAT_SRODATA:
1925 case SECCAT_SDATA:
1926 case SECCAT_SBSS:
1927 /* Thread-local storage (TLS) is not supported. */
1928 case SECCAT_TDATA:
1929 case SECCAT_TBSS:
1930 /* Sections used by a dynamic linker are not supported. */
1931 case SECCAT_DATA_REL:
1932 case SECCAT_DATA_REL_LOCAL:
1933 case SECCAT_DATA_REL_RO:
1934 case SECCAT_DATA_REL_RO_LOCAL:
1935 return default_select_section (decl, reloc, align);
1936
1937 default:
1938 gcc_unreachable ();
1939 }
1940
1941 sec_name = ACONCAT ((prefix, base_sec_name, DECL_SECTION_NAME (decl), NULL));
1942
1943 return get_named_section (decl, sec_name, 0);
1944 }
1945
1946 #undef TARGET_ASM_FUNCTION_SECTION
1947 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1948
1949 static section *
msp430_function_section(tree decl,enum node_frequency freq,bool startup,bool exit)1950 msp430_function_section (tree decl, enum node_frequency freq, bool startup,
1951 bool exit)
1952 {
1953 const char * name;
1954
1955 gcc_assert (DECL_SECTION_NAME (decl) != NULL);
1956 name = DECL_SECTION_NAME (decl);
1957
1958 const char * prefix = gen_prefix (decl);
1959 if (prefix == NULL
1960 || strncmp (name, prefix, strlen (prefix)) == 0)
1961 return default_function_section (decl, freq, startup, exit);
1962
1963 name = ACONCAT ((prefix, name, NULL));
1964 return get_named_section (decl, name, 0);
1965 }
1966
1967 #undef TARGET_SECTION_TYPE_FLAGS
1968 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1969
1970 unsigned int
msp430_section_type_flags(tree decl,const char * name,int reloc)1971 msp430_section_type_flags (tree decl, const char * name, int reloc)
1972 {
1973 if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0)
1974 name += strlen (lower_prefix);
1975 else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0)
1976 name += strlen (upper_prefix);
1977 else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
1978 name += strlen (either_prefix);
1979 else if (strcmp (name, ".persistent") == 0)
1980 return SECTION_WRITE | SECTION_NOTYPE;
1981
1982 return default_section_type_flags (decl, name, reloc);
1983 }
1984
1985 #undef TARGET_ASM_UNIQUE_SECTION
1986 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1987
1988 static void
msp430_unique_section(tree decl,int reloc)1989 msp430_unique_section (tree decl, int reloc)
1990 {
1991 gcc_assert (decl != NULL_TREE);
1992
1993 /* In large mode we must make sure that interrupt handlers are put into
1994 low memory as the vector table only accepts 16-bit addresses. */
1995 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
1996 && is_interrupt_func (decl))
1997 {
1998 set_decl_section_name (decl, ".lowtext");
1999 return;
2000 }
2001
2002 default_unique_section (decl, reloc);
2003
2004 const char * prefix;
2005
2006 if ( TREE_CODE (decl) == STRING_CST
2007 || TREE_CODE (decl) == CONSTRUCTOR
2008 || TREE_CODE (decl) == INTEGER_CST
2009 || TREE_CODE (decl) == VECTOR_CST
2010 || TREE_CODE (decl) == COMPLEX_CST
2011 || (prefix = gen_prefix (decl)) == NULL)
2012 return;
2013
2014 const char * dec_name = DECL_SECTION_NAME (decl);
2015 char * name = ACONCAT ((prefix, dec_name, NULL));
2016
2017 set_decl_section_name (decl, name);
2018 }
2019
2020 /* Emit a declaration of a common symbol.
2021 If a data region is in use then put the symbol into the
2022 equivalent .bss section instead. */
2023 void
msp430_output_aligned_decl_common(FILE * stream,const tree decl,const char * name,unsigned HOST_WIDE_INT size,unsigned int align)2024 msp430_output_aligned_decl_common (FILE * stream,
2025 const tree decl,
2026 const char * name,
2027 unsigned HOST_WIDE_INT size,
2028 unsigned int align)
2029 {
2030 /* Only emit a common symbol if the variable does not have a specific section
2031 assigned. */
2032 if ((msp430_data_region == MSP430_REGION_ANY
2033 || ((msp430_data_region == MSP430_REGION_LOWER)
2034 && !TARGET_USE_LOWER_REGION_PREFIX))
2035 && !(decl != NULL_TREE && DECL_SECTION_NAME (decl))
2036 && !has_attr (ATTR_EITHER, decl)
2037 && !has_attr (ATTR_LOWER, decl)
2038 && !has_attr (ATTR_UPPER, decl)
2039 && !has_attr (ATTR_PERSIST, decl)
2040 && !has_attr (ATTR_NOINIT, decl))
2041 {
2042 fprintf (stream, COMMON_ASM_OP);
2043 assemble_name (stream, name);
2044 fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
2045 size, align / BITS_PER_UNIT);
2046 }
2047 else
2048 {
2049 section * sec;
2050
2051 if (decl)
2052 sec = msp430_select_section (decl, 0, align);
2053 else
2054 switch (msp430_data_region)
2055 {
2056 case MSP430_REGION_UPPER:
2057 sec = get_named_section (NULL, ".upper.bss", 0);
2058 break;
2059 case MSP430_REGION_LOWER:
2060 sec = get_named_section (NULL, ".lower.bss", 0);
2061 break;
2062 case MSP430_REGION_EITHER:
2063 sec = get_named_section (NULL, ".either.bss", 0);
2064 break;
2065 default:
2066 gcc_unreachable ();
2067 }
2068 gcc_assert (sec != NULL);
2069
2070 switch_to_section (sec);
2071 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
2072 targetm.asm_out.globalize_label (stream, name);
2073 ASM_WEAKEN_LABEL (stream, name);
2074 ASM_OUTPUT_LABEL (stream, name);
2075 ASM_OUTPUT_SKIP (stream, size ? size : 1);
2076 }
2077 }
2078
2079 #undef TARGET_ASM_FILE_END
2080 #define TARGET_ASM_FILE_END msp430_file_end
2081
2082 /* Emit MSPABI and GNU object attributes.
2083 Tags and values for MSPABI attributes are:
2084 OFBA_MSPABI_Tag_ISA 4
2085 MSP430 1
2086 MSP430X 2
2087 OFBA_MSPABI_Tag_Code_Model 6
2088 Small 1
2089 Large 2
2090 OFBA_MSPABI_Tag_Data_Model 8
2091 Small 1
2092 Large 2
2093 Restricted 3 (Unused by GNU)
2094 OFBA_MSPABI_Tag_enum_size 10 (Unused by GNU)
2095 Note that Code_Model and Data_Model are always equal for GNU.
2096 We define a new .gnu_attribute to keep track of the data region used.
2097 Tag_GNU_MSP430_Data_Region 4
2098 LOWER 1
2099 ANY 2
2100 See binutils-gdb/include/elf/msp430.h for the full details. */
2101 static void
msp430_file_end(void)2102 msp430_file_end (void)
2103 {
2104 #ifdef HAVE_AS_GNU_ATTRIBUTE
2105 /* Enum for tag names. */
2106 enum
2107 {
2108 OFBA_MSPABI_Tag_ISA = 4,
2109 OFBA_MSPABI_Tag_Code_Model = 6,
2110 OFBA_MSPABI_Tag_Data_Model = 8,
2111 Tag_GNU_MSP430_Data_Region = 4
2112 };
2113 /* Enum for tag values. */
2114 enum
2115 {
2116 OFBA_MSPABI_Val_ISA_MSP430 = 1,
2117 OFBA_MSPABI_Val_ISA_MSP430X = 2,
2118 OFBA_MSPABI_Val_Model_Small = 1,
2119 OFBA_MSPABI_Val_Model_Large = 2,
2120 Tag_GNU_MSP430_Data_Region_Lower = 1,
2121 Tag_GNU_MSP430_Data_Region_Any = 2
2122 };
2123 /* .mspabi_attribute is a GNU assembler directive only. The assembler will
2124 construct a .MSP430.attributes section based on the options it is invoked
2125 with. The values it reads from these directives are used for validating
2126 those options. */
2127 const char *msp430_attr = ".mspabi_attribute";
2128 const char *gnu_attr = ".gnu_attribute";
2129
2130 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_ISA. */
2131 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr, OFBA_MSPABI_Tag_ISA,
2132 msp430x ? OFBA_MSPABI_Val_ISA_MSP430X : OFBA_MSPABI_Val_ISA_MSP430);
2133 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Code_Model. */
2134 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2135 OFBA_MSPABI_Tag_Code_Model,
2136 TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2137 : OFBA_MSPABI_Val_Model_Small);
2138 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Data_Model. */
2139 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2140 OFBA_MSPABI_Tag_Data_Model,
2141 TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2142 : OFBA_MSPABI_Val_Model_Small);
2143 #ifdef HAVE_AS_MSPABI_ATTRIBUTE
2144 /* Emit .gnu_attribute directive for Tag_GNU_MSP430_Data_Region. */
2145 fprintf (asm_out_file, "\t%s %d, %d\n", gnu_attr, Tag_GNU_MSP430_Data_Region,
2146 msp430_data_region == MSP430_REGION_LOWER
2147 ? Tag_GNU_MSP430_Data_Region_Lower
2148 : Tag_GNU_MSP430_Data_Region_Any);
2149 #endif
2150 #endif
2151 }
2152
2153 bool
msp430_do_not_relax_short_jumps(void)2154 msp430_do_not_relax_short_jumps (void)
2155 {
2156 /* When placing code into "either" low or high memory we do not want the
2157 linker to grow the size of sections, which it can do if it is encounters a
2158 branch to a label that is too far away. So we tell the cbranch patterns to
2159 avoid using short jumps when there is a chance that the instructions will
2160 end up in a low section. */
2161 return
2162 msp430_code_region == MSP430_REGION_EITHER
2163 || has_attr (ATTR_EITHER, current_function_decl);
2164 }
2165
2166 enum msp430_builtin
2167 {
2168 MSP430_BUILTIN_BIC_SR,
2169 MSP430_BUILTIN_BIS_SR,
2170 MSP430_BUILTIN_DELAY_CYCLES,
2171 MSP430_BUILTIN_max
2172 };
2173
2174 static GTY(()) tree msp430_builtins[(int) MSP430_BUILTIN_max];
2175
2176 static void
msp430_init_builtins(void)2177 msp430_init_builtins (void)
2178 {
2179 tree void_ftype_int = build_function_type_list (void_type_node,
2180 integer_type_node, NULL);
2181 tree void_ftype_longlong
2182 = build_function_type_list (void_type_node, long_long_integer_type_node,
2183 NULL);
2184
2185 msp430_builtins[MSP430_BUILTIN_BIC_SR] =
2186 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
2187 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
2188
2189 msp430_builtins[MSP430_BUILTIN_BIS_SR] =
2190 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
2191 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
2192
2193 msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
2194 add_builtin_function ( "__delay_cycles", void_ftype_longlong,
2195 MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL,
2196 NULL_TREE);
2197 }
2198
2199 static tree
msp430_builtin_decl(unsigned code,bool initialize ATTRIBUTE_UNUSED)2200 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
2201 {
2202 switch (code)
2203 {
2204 case MSP430_BUILTIN_BIC_SR:
2205 case MSP430_BUILTIN_BIS_SR:
2206 case MSP430_BUILTIN_DELAY_CYCLES:
2207 return msp430_builtins[code];
2208 default:
2209 return error_mark_node;
2210 }
2211 }
2212
2213 /* These constants are really register reads, which are faster than
2214 regular constants. */
2215 static int
cg_magic_constant(HOST_WIDE_INT c)2216 cg_magic_constant (HOST_WIDE_INT c)
2217 {
2218 switch (c)
2219 {
2220 case 0xffff:
2221 case -1:
2222 case 0:
2223 case 1:
2224 case 2:
2225 case 4:
2226 case 8:
2227 return 1;
2228 default:
2229 return 0;
2230 }
2231 }
2232
2233 static rtx
msp430_expand_delay_cycles(rtx arg)2234 msp430_expand_delay_cycles (rtx arg)
2235 {
2236 HOST_WIDE_INT i, c, n;
2237 /* extra cycles for MSP430X instructions */
2238 #define CYCX(M,X) (msp430x ? (X) : (M))
2239
2240 if (GET_CODE (arg) != CONST_INT)
2241 {
2242 error ("__delay_cycles() only takes constant arguments");
2243 return NULL_RTX;
2244 }
2245
2246 c = INTVAL (arg);
2247
2248 if (HOST_BITS_PER_WIDE_INT > 32)
2249 {
2250 if (c < 0)
2251 {
2252 error ("__delay_cycles only takes non-negative cycle counts");
2253 return NULL_RTX;
2254 }
2255 }
2256
2257 emit_insn (gen_delay_cycles_start (arg));
2258
2259 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
2260 if (c > 3 * 0xffff + CYCX (7, 10))
2261 {
2262 n = c;
2263 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long
2264 (x<=0xffff) loop. */
2265 if (c >= 0x10000 * 7 + CYCX (14, 16))
2266 {
2267 i = 0x10000;
2268 c -= CYCX (14, 16) + 7 * 0x10000;
2269 i += c / 4;
2270 c %= 4;
2271 if ((unsigned long long) i > 0xffffffffULL)
2272 {
2273 error ("__delay_cycles is limited to 32-bit loop counts");
2274 return NULL_RTX;
2275 }
2276 }
2277 else
2278 {
2279 i = (c - CYCX (14, 16)) / 7;
2280 c -= CYCX (14, 16) + i * 7;
2281 }
2282
2283 if (cg_magic_constant (i & 0xffff))
2284 c ++;
2285 if (cg_magic_constant ((i >> 16) & 0xffff))
2286 c ++;
2287
2288 if (msp430x)
2289 emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c)));
2290 else
2291 emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
2292 }
2293
2294 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is
2295 0x30004(7). */
2296 if (c > 12)
2297 {
2298 n = c;
2299 i = (c - CYCX (7, 10)) / 3;
2300 c -= CYCX (7, 10) + i * 3;
2301
2302 if (cg_magic_constant (i))
2303 c ++;
2304
2305 if (msp430x)
2306 emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c)));
2307 else
2308 emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c)));
2309 }
2310
2311 while (c > 1)
2312 {
2313 emit_insn (gen_delay_cycles_2 ());
2314 c -= 2;
2315 }
2316
2317 if (c)
2318 {
2319 emit_insn (gen_delay_cycles_1 ());
2320 c -= 1;
2321 }
2322
2323 emit_insn (gen_delay_cycles_end (arg));
2324
2325 return NULL_RTX;
2326 }
2327
2328 static rtx
msp430_expand_builtin(tree exp,rtx target ATTRIBUTE_UNUSED,rtx subtarget ATTRIBUTE_UNUSED,machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)2329 msp430_expand_builtin (tree exp,
2330 rtx target ATTRIBUTE_UNUSED,
2331 rtx subtarget ATTRIBUTE_UNUSED,
2332 machine_mode mode ATTRIBUTE_UNUSED,
2333 int ignore ATTRIBUTE_UNUSED)
2334 {
2335 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2336 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
2337 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2338
2339 if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
2340 return msp430_expand_delay_cycles (arg1);
2341
2342 if (! msp430_is_interrupt_func ())
2343 {
2344 error ("MSP430 builtin functions only work inside interrupt handlers");
2345 return NULL_RTX;
2346 }
2347
2348 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
2349 arg1 = force_reg (mode, arg1);
2350
2351 switch (fcode)
2352 {
2353 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break;
2354 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break;
2355 default:
2356 internal_error ("bad builtin code");
2357 break;
2358 }
2359 return NULL_RTX;
2360 }
2361
2362 #undef TARGET_INIT_BUILTINS
2363 #define TARGET_INIT_BUILTINS msp430_init_builtins
2364
2365 #undef TARGET_EXPAND_BUILTIN
2366 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
2367
2368 #undef TARGET_BUILTIN_DECL
2369 #define TARGET_BUILTIN_DECL msp430_builtin_decl
2370
2371 void
msp430_expand_prologue(void)2372 msp430_expand_prologue (void)
2373 {
2374 int i, j;
2375 int fs;
2376 /* Always use stack_pointer_rtx instead of calling
2377 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
2378 that there is a single rtx representing the stack pointer,
2379 namely stack_pointer_rtx, and uses == to recognize it. */
2380 rtx sp = stack_pointer_rtx;
2381 rtx p;
2382
2383 if (is_naked_func ())
2384 {
2385 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2386 examines the output of the gen_prologue() function. */
2387 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2388 return;
2389 }
2390
2391 emit_insn (gen_prologue_start_marker ());
2392
2393 if (is_critical_func ())
2394 {
2395 emit_insn (gen_push_intr_state ());
2396 emit_insn (gen_disable_interrupts ());
2397 }
2398 else if (is_reentrant_func ())
2399 emit_insn (gen_disable_interrupts ());
2400
2401 if (!cfun->machine->computed)
2402 msp430_compute_frame_info ();
2403
2404 if (flag_stack_usage_info)
2405 current_function_static_stack_size = cfun->machine->framesize;
2406
2407 if (crtl->args.pretend_args_size)
2408 {
2409 rtx note;
2410
2411 gcc_assert (crtl->args.pretend_args_size == 2);
2412
2413 p = emit_insn (gen_grow_and_swap ());
2414
2415 /* Document the stack decrement... */
2416 note = F (gen_rtx_SET (stack_pointer_rtx,
2417 gen_rtx_MINUS (Pmode,
2418 stack_pointer_rtx, GEN_INT (2))));
2419 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2420
2421 /* ...and the establishment of a new location for the return address. */
2422 note = F (gen_rtx_SET (gen_rtx_MEM (Pmode,
2423 gen_rtx_PLUS (Pmode,
2424 stack_pointer_rtx,
2425 GEN_INT (-2))),
2426 pc_rtx));
2427 add_reg_note (p, REG_CFA_OFFSET, note);
2428 F (p);
2429 }
2430
2431 for (i = 15; i >= 4; i--)
2432 if (cfun->machine->need_to_save[i])
2433 {
2434 int seq, count;
2435 rtx note;
2436
2437 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
2438 ;
2439 count = i - seq;
2440
2441 if (msp430x)
2442 {
2443 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two
2444 bytes bigger. */
2445 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
2446 GEN_INT (count))));
2447
2448 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2449
2450 XVECEXP (note, 0, 0)
2451 = F (gen_rtx_SET (stack_pointer_rtx,
2452 gen_rtx_PLUS (Pmode,
2453 stack_pointer_rtx,
2454 GEN_INT (count * (TARGET_LARGE
2455 ? -4 : -2)))));
2456
2457 /* *sp-- = R[i-j] */
2458 /* sp+N R10
2459 ...
2460 sp R4 */
2461 for (j = 0; j < count; j ++)
2462 {
2463 rtx addr;
2464 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2465
2466 if (ofs)
2467 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2468 else
2469 addr = stack_pointer_rtx;
2470
2471 XVECEXP (note, 0, j + 1) =
2472 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2473 gen_rtx_REG (Pmode, i - j)));
2474 }
2475
2476 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2477 i -= count - 1;
2478 }
2479 else
2480 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2481 }
2482
2483 if (frame_pointer_needed)
2484 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2485
2486 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2487
2488 increment_stack (- fs);
2489
2490 emit_insn (gen_prologue_end_marker ());
2491 }
2492
2493 void
msp430_expand_epilogue(int is_eh)2494 msp430_expand_epilogue (int is_eh)
2495 {
2496 int i;
2497 int fs;
2498 int helper_n = 0;
2499
2500 if (is_naked_func ())
2501 {
2502 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2503 examines the output of the gen_epilogue() function. */
2504 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2505 return;
2506 }
2507
2508 if (cfun->machine->need_to_save[10])
2509 {
2510 /* Check for a helper function. */
2511 helper_n = 7; /* For when the loop below never sees a match. */
2512 for (i = 9; i >= 4; i--)
2513 if (!cfun->machine->need_to_save[i])
2514 {
2515 helper_n = 10 - i;
2516 for (; i >= 4; i--)
2517 if (cfun->machine->need_to_save[i])
2518 {
2519 helper_n = 0;
2520 break;
2521 }
2522 break;
2523 }
2524 }
2525
2526 emit_insn (gen_epilogue_start_marker ());
2527
2528 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)),
2529 "main") == 0)
2530 emit_insn (gen_msp430_refsym_need_exit ());
2531
2532 if (is_wakeup_func ())
2533 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2534 status register current residing on the stack. When this function
2535 executes its RETI instruction the SR will be updated with this saved
2536 value, thus ensuring that the processor is woken up from any low power
2537 state in which it may be residing. */
2538 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2539
2540 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2541
2542 increment_stack (fs);
2543
2544 if (is_eh)
2545 {
2546 /* We need to add the right "SP" register save just after the
2547 regular ones, so that when we pop it off we're in the EH
2548 return frame, not this one. This overwrites our own return
2549 address, but we're not going to be returning anyway. */
2550 rtx r12 = gen_rtx_REG (Pmode, 12);
2551 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
2552
2553 /* R12 will hold the new SP. */
2554 i = cfun->machine->framesize_regs;
2555 emit_move_insn (r12, stack_pointer_rtx);
2556 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
2557 emit_insn (addPmode (r12, r12, GEN_INT (i)));
2558 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode,
2559 stack_pointer_rtx,
2560 i)), r12);
2561 }
2562
2563 for (i = 4; i <= 15; i++)
2564 if (cfun->machine->need_to_save[i])
2565 {
2566 int seq, count;
2567
2568 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
2569 ;
2570 count = seq - i;
2571
2572 if (msp430x)
2573 {
2574 /* Note: With TARGET_LARGE we still use
2575 POPM as POPX.A is two bytes bigger. */
2576 emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
2577 GEN_INT (count)));
2578 i += count - 1;
2579 }
2580 else if (i == 11 - helper_n
2581 && ! msp430_is_interrupt_func ()
2582 && ! is_reentrant_func ()
2583 && ! is_critical_func ()
2584 && crtl->args.pretend_args_size == 0
2585 /* Calling the helper takes as many bytes as the POP;RET
2586 sequence. */
2587 && helper_n > 1
2588 && !is_eh)
2589 {
2590 emit_jump_insn (gen_epilogue_helper (GEN_INT (helper_n)));
2591 return;
2592 }
2593 else
2594 emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
2595 }
2596
2597 if (is_eh)
2598 {
2599 /* Also pop SP, which puts us into the EH return frame. Except
2600 that you can't "pop" sp, you have to just load it off the
2601 stack. */
2602 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode,
2603 stack_pointer_rtx));
2604 }
2605
2606 if (crtl->args.pretend_args_size)
2607 emit_insn (gen_swap_and_shrink ());
2608
2609 if (is_critical_func ())
2610 emit_insn (gen_pop_intr_state ());
2611 else if (is_reentrant_func ())
2612 emit_insn (gen_enable_interrupts ());
2613
2614 emit_jump_insn (gen_msp430_return ());
2615 }
2616
2617 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2618 m32c_emit_eh_epilogue. */
2619 rtx
msp430_eh_return_stackadj_rtx(void)2620 msp430_eh_return_stackadj_rtx (void)
2621 {
2622 if (!cfun->machine->eh_stack_adjust)
2623 {
2624 rtx sa;
2625
2626 sa = gen_rtx_REG (Pmode, 15);
2627 cfun->machine->eh_stack_adjust = sa;
2628 }
2629 return cfun->machine->eh_stack_adjust;
2630 }
2631
2632 /* This function is called before reload, to "fix" the stack in
2633 preparation for an EH return. */
2634 void
msp430_expand_eh_return(rtx eh_handler)2635 msp430_expand_eh_return (rtx eh_handler)
2636 {
2637 /* These are all Pmode */
2638 rtx ap, sa, ra, tmp;
2639
2640 ap = arg_pointer_rtx;
2641 sa = msp430_eh_return_stackadj_rtx ();
2642 ra = eh_handler;
2643
2644 tmp = ap;
2645 tmp = gen_rtx_PLUS (Pmode, ap, sa);
2646 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
2647 tmp = gen_rtx_MEM (Pmode, tmp);
2648 emit_move_insn (tmp, ra);
2649 }
2650
2651 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
2652 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2653 void
msp430_init_dwarf_reg_sizes_extra(tree address)2654 msp430_init_dwarf_reg_sizes_extra (tree address)
2655 {
2656 int i;
2657 rtx addr = expand_normal (address);
2658 rtx mem = gen_rtx_MEM (BLKmode, addr);
2659
2660 /* This needs to match msp430_unwind_word_mode (above). */
2661 if (!msp430x)
2662 return;
2663
2664 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2665 {
2666 unsigned int dnum = DWARF_FRAME_REGNUM (i);
2667 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
2668
2669 if (rnum < DWARF_FRAME_REGISTERS)
2670 {
2671 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
2672
2673 emit_move_insn (adjust_address (mem, QImode, offset),
2674 gen_int_mode (4, QImode));
2675 }
2676 }
2677 }
2678
2679 /* This is a list of MD patterns that implement fixed-count shifts. */
2680 static struct
2681 {
2682 const char *name;
2683 int count;
2684 int need_430x;
2685 rtx (*genfunc)(rtx,rtx);
2686 }
2687 const_shift_helpers[] =
2688 {
2689 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2690
2691 CSH ("slli", 1, 1, slli_1),
2692 CSH ("slll", 1, 1, slll_1),
2693 CSH ("slll", 2, 1, slll_2),
2694
2695 CSH ("srai", 1, 0, srai_1),
2696 CSH ("sral", 1, 0, sral_1),
2697 CSH ("sral", 2, 0, sral_2),
2698
2699 CSH ("srll", 1, 0, srll_1),
2700 CSH ("srll", 2, 1, srll_2x),
2701 { 0, 0, 0, 0 }
2702 #undef CSH
2703 };
2704
2705 /* The MSP430 ABI defines a number of helper functions that should be
2706 used for, for example, 32-bit shifts. This function is called to
2707 emit such a function, using the table above to optimize some
2708 cases. */
2709 void
msp430_expand_helper(rtx * operands,const char * helper_name,bool const_variants)2710 msp430_expand_helper (rtx *operands, const char *helper_name,
2711 bool const_variants)
2712 {
2713 rtx c, fusage, fsym;
2714 char *helper_const = NULL;
2715 int arg1 = 12;
2716 int arg2 = 13;
2717 int arg1sz = 1;
2718 machine_mode arg0mode = GET_MODE (operands[0]);
2719 machine_mode arg1mode = GET_MODE (operands[1]);
2720 machine_mode arg2mode = GET_MODE (operands[2]);
2721 int have_430x = msp430x ? 1 : 0;
2722 int expand_mpy = strncmp (helper_name, "__mspabi_mpy",
2723 sizeof ("__mspabi_mpy") - 1) == 0;
2724 /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a
2725 hwmpy function. */
2726 gcc_assert (!(expand_mpy && const_variants));
2727
2728 /* Emit size-optimal insns for small shifts we can easily do inline. */
2729 if (CONST_INT_P (operands[2]) && !expand_mpy)
2730 {
2731 int i;
2732
2733 for (i=0; const_shift_helpers[i].name; i++)
2734 {
2735 if (const_shift_helpers[i].need_430x <= have_430x
2736 && strcmp (helper_name, const_shift_helpers[i].name) == 0
2737 && INTVAL (operands[2]) == const_shift_helpers[i].count)
2738 {
2739 emit_insn (const_shift_helpers[i].genfunc (operands[0],
2740 operands[1]));
2741 return;
2742 }
2743 }
2744 }
2745
2746 if (arg1mode != VOIDmode && arg2mode != VOIDmode)
2747 /* Modes of arguments must be equal if not constants. */
2748 gcc_assert (arg1mode == arg2mode);
2749
2750 if (arg1mode == VOIDmode)
2751 arg1mode = arg0mode;
2752 if (arg2mode == VOIDmode)
2753 arg2mode = arg0mode;
2754
2755 if (arg1mode == SImode)
2756 {
2757 arg2 = 14;
2758 arg1sz = 2;
2759 }
2760 else if (arg1mode == DImode)
2761 {
2762 arg1 = 8;
2763 arg1sz = 4;
2764 arg2 = 12;
2765 }
2766
2767 /* Use the "const_variant" of a shift library function if requested.
2768 These are faster, but have larger code size. */
2769 if (const_variants
2770 && CONST_INT_P (operands[2])
2771 && INTVAL (operands[2]) >= 1
2772 && INTVAL (operands[2]) <= 15)
2773 {
2774 /* Note that the INTVAL is limited in value and length by the conditional
2775 above. */
2776 int len = strlen (helper_name) + 4;
2777 helper_const = (char *) xmalloc (len);
2778 snprintf (helper_const, len, "%s_%d", helper_name,
2779 (int) INTVAL (operands[2]));
2780 }
2781
2782 /* Setup the arguments to the helper function. */
2783 emit_move_insn (gen_rtx_REG (arg1mode, arg1),
2784 operands[1]);
2785 if (!helper_const)
2786 emit_move_insn (gen_rtx_REG (arg2mode, arg2),
2787 operands[2]);
2788
2789 if (expand_mpy)
2790 {
2791 if (msp430_use_f5_series_hwmult ())
2792 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2793 "_f5hw", NULL));
2794 else if (use_32bit_hwmult ())
2795 {
2796 /* When the arguments are 16-bits, the 16-bit hardware multiplier is
2797 used. */
2798 if (arg1mode == HImode)
2799 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2800 "_hw", NULL));
2801 else
2802 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2803 "_hw32", NULL));
2804 }
2805 /* 16-bit hardware multiply. */
2806 else if (msp430_has_hwmult ())
2807 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2808 "_hw", NULL));
2809 else
2810 fsym = gen_rtx_SYMBOL_REF (VOIDmode, helper_name);
2811 }
2812 else
2813 fsym = gen_rtx_SYMBOL_REF (VOIDmode,
2814 helper_const ? helper_const : helper_name);
2815
2816 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), fsym, GEN_INT (0));
2817
2818 c = emit_call_insn (c);
2819 RTL_CONST_CALL_P (c) = 1;
2820
2821 /* Add register usage information for the arguments to the call. */
2822 fusage = NULL;
2823 use_regs (&fusage, arg1, arg1sz);
2824 if (!helper_const)
2825 {
2826 /* If we are expanding a shift, we only need to use the low register
2827 for the shift amount. */
2828 if (!expand_mpy)
2829 use_regs (&fusage, arg2, 1);
2830 else
2831 use_regs (&fusage, arg2, arg1sz);
2832 }
2833 add_function_usage_to (c, fusage);
2834
2835 emit_move_insn (operands[0],
2836 /* Return value will always start in R12. */
2837 gen_rtx_REG (arg0mode, 12));
2838 }
2839
2840 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
2841 void
msp430_fixup_compare_operands(machine_mode my_mode,rtx * operands)2842 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
2843 {
2844 /* constants we're looking for, not constants which are allowed. */
2845 int const_op_idx = 1;
2846
2847 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
2848 const_op_idx = 2;
2849
2850 if (GET_CODE (operands[const_op_idx]) != REG
2851 && GET_CODE (operands[const_op_idx]) != MEM)
2852 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
2853 }
2854
2855 /* Simplify_gen_subreg() doesn't handle memory references the way we
2856 need it to below, so we use this function for when we must get a
2857 valid subreg in a "natural" state. */
2858 rtx
msp430_subreg(machine_mode mode,rtx r,machine_mode omode,int byte)2859 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
2860 {
2861 rtx rv;
2862 gcc_assert (mode == HImode);
2863
2864 if (GET_CODE (r) == SUBREG
2865 && SUBREG_BYTE (r) == 0)
2866 {
2867 rtx ireg = SUBREG_REG (r);
2868 machine_mode imode = GET_MODE (ireg);
2869
2870 /* special case for (HI (SI (PSI ...), 0)) */
2871 if (imode == PSImode
2872 && mode == HImode
2873 && byte == 0)
2874 rv = gen_rtx_SUBREG (mode, ireg, byte);
2875 else
2876 rv = simplify_gen_subreg (mode, ireg, imode, byte);
2877 }
2878 else if (GET_CODE (r) == MEM)
2879 {
2880 /* When byte == 2, we can be certain that we were already called with an
2881 identical rtx with byte == 0. So we don't need to do anything to
2882 get a 2 byte offset of a (mem (post_inc)) rtx, since the address has
2883 already been offset by the post_inc itself. */
2884 if (GET_CODE (XEXP (r, 0)) == POST_INC && byte == 2)
2885 byte = 0;
2886 rv = adjust_address (r, mode, byte);
2887 }
2888 else if (GET_CODE (r) == SYMBOL_REF
2889 && (byte == 0 || byte == 2)
2890 && mode == HImode)
2891 {
2892 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
2893 rv = gen_rtx_CONST (HImode, r);
2894 }
2895 else
2896 rv = simplify_gen_subreg (mode, r, omode, byte);
2897
2898 if (!rv)
2899 gcc_unreachable ();
2900
2901 return rv;
2902 }
2903
2904 int
msp430_split_addsi(rtx * operands)2905 msp430_split_addsi (rtx *operands)
2906 {
2907 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
2908 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
2909 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
2910 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
2911 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
2912 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
2913
2914 /* BZ 64160: Do not use this splitter when the dest partially overlaps the
2915 source. */
2916 if (reg_overlap_mentioned_p (operands[3], operands[7])
2917 || reg_overlap_mentioned_p (operands[3], operands[8]))
2918 return 1;
2919
2920 if (GET_CODE (operands[5]) == CONST_INT)
2921 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
2922 /* Handle post_inc, for example:
2923 (set (reg:SI)
2924 (plus:SI (reg:SI)
2925 (mem:SI (post_inc:PSI (reg:PSI))))). */
2926 else if (MEM_P (operands[5]) && GET_CODE (XEXP (operands[5], 0)) == POST_INC)
2927 {
2928 /* Strip out the post_inc from (mem (post_inc (reg))). */
2929 operands[9] = XEXP (XEXP (operands[5], 0), 0);
2930 operands[9] = gen_rtx_MEM (HImode, operands[9]);
2931 /* Then zero extend as normal. */
2932 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[9]);
2933 }
2934 else
2935 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
2936 return 0;
2937 }
2938
2939 /* Called by movsi_x to generate the HImode operands. */
2940 void
msp430_split_movsi(rtx * operands)2941 msp430_split_movsi (rtx *operands)
2942 {
2943 rtx op00, op02, op10, op12;
2944
2945 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
2946 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
2947
2948 if (GET_CODE (operands[1]) == CONST
2949 || GET_CODE (operands[1]) == SYMBOL_REF)
2950 {
2951 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
2952 GEN_INT (0));
2953 op10 = gen_rtx_CONST (HImode, op10);
2954 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
2955 GEN_INT (16));
2956 op12 = gen_rtx_CONST (HImode, op12);
2957 }
2958 else
2959 {
2960 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
2961 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
2962 }
2963
2964 if (rtx_equal_p (operands[0], operands[1]))
2965 {
2966 operands[2] = op02;
2967 operands[4] = op12;
2968 operands[3] = op00;
2969 operands[5] = op10;
2970 }
2971 else if (rtx_equal_p (op00, op12)
2972 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
2973 || (REG_P (op00) && reg_mentioned_p (op00, op10))
2974 /* Or storing (rN) into mem (rN). */
2975 || (REG_P (op10) && reg_mentioned_p (op10, op00)))
2976 {
2977 operands[2] = op02;
2978 operands[4] = op12;
2979 operands[3] = op00;
2980 operands[5] = op10;
2981 }
2982 else
2983 {
2984 operands[2] = op00;
2985 operands[4] = op10;
2986 operands[3] = op02;
2987 operands[5] = op12;
2988 }
2989 }
2990
2991
2992 /* The MSPABI specifies the names of various helper functions, many of
2993 which are compatible with GCC's helpers. This table maps the GCC
2994 name to the MSPABI name. */
2995 static const struct
2996 {
2997 char const * const gcc_name;
2998 char const * const ti_name;
2999 }
3000 helper_function_name_mappings[] =
3001 {
3002 /* Floating point to/from integer conversions. */
3003 { "__truncdfsf2", "__mspabi_cvtdf" },
3004 { "__extendsfdf2", "__mspabi_cvtfd" },
3005 { "__fixdfhi", "__mspabi_fixdi" },
3006 { "__fixdfsi", "__mspabi_fixdli" },
3007 { "__fixdfdi", "__mspabi_fixdlli" },
3008 { "__fixunsdfhi", "__mspabi_fixdu" },
3009 { "__fixunsdfsi", "__mspabi_fixdul" },
3010 { "__fixunsdfdi", "__mspabi_fixdull" },
3011 { "__fixsfhi", "__mspabi_fixfi" },
3012 { "__fixsfsi", "__mspabi_fixfli" },
3013 { "__fixsfdi", "__mspabi_fixflli" },
3014 { "__fixunsfhi", "__mspabi_fixfu" },
3015 { "__fixunsfsi", "__mspabi_fixful" },
3016 { "__fixunsfdi", "__mspabi_fixfull" },
3017 { "__floathisf", "__mspabi_fltif" },
3018 { "__floatsisf", "__mspabi_fltlif" },
3019 { "__floatdisf", "__mspabi_fltllif" },
3020 { "__floathidf", "__mspabi_fltid" },
3021 { "__floatsidf", "__mspabi_fltlid" },
3022 { "__floatdidf", "__mspabi_fltllid" },
3023 { "__floatunhisf", "__mspabi_fltuf" },
3024 { "__floatunsisf", "__mspabi_fltulf" },
3025 { "__floatundisf", "__mspabi_fltullf" },
3026 { "__floatunhidf", "__mspabi_fltud" },
3027 { "__floatunsidf", "__mspabi_fltuld" },
3028 { "__floatundidf", "__mspabi_fltulld" },
3029
3030 /* Floating point comparisons. */
3031 /* GCC uses individual functions for each comparison, TI uses one
3032 compare <=> function. */
3033
3034 /* Floating point arithmetic. */
3035 { "__adddf3", "__mspabi_addd" },
3036 { "__addsf3", "__mspabi_addf" },
3037 { "__divdf3", "__mspabi_divd" },
3038 { "__divsf3", "__mspabi_divf" },
3039 { "__muldf3", "__mspabi_mpyd" },
3040 { "__mulsf3", "__mspabi_mpyf" },
3041 { "__subdf3", "__mspabi_subd" },
3042 { "__subsf3", "__mspabi_subf" },
3043 /* GCC does not use helper functions for negation. */
3044
3045 /* Integer multiply, divide, remainder. */
3046 { "__mulhi3", "__mspabi_mpyi" },
3047 { "__mulsi3", "__mspabi_mpyl" },
3048 { "__muldi3", "__mspabi_mpyll" },
3049 #if 0
3050 /* Clarify signed vs unsigned first. */
3051 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
3052 (yet?) */
3053 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
3054 (yet?) */
3055 #endif
3056
3057 { "__divhi3", "__mspabi_divi" },
3058 { "__divsi3", "__mspabi_divli" },
3059 { "__divdi3", "__mspabi_divlli" },
3060 { "__udivhi3", "__mspabi_divu" },
3061 { "__udivsi3", "__mspabi_divul" },
3062 { "__udivdi3", "__mspabi_divull" },
3063 { "__modhi3", "__mspabi_remi" },
3064 { "__modsi3", "__mspabi_remli" },
3065 { "__moddi3", "__mspabi_remlli" },
3066 { "__umodhi3", "__mspabi_remu" },
3067 { "__umodsi3", "__mspabi_remul" },
3068 { "__umoddi3", "__mspabi_remull" },
3069
3070 /* Bitwise operations. */
3071 /* Rotation - no rotation support yet. */
3072 /* Logical left shift - gcc already does these itself. */
3073 /* Arithmetic left shift - gcc already does these itself. */
3074 /* Arithmetic right shift - gcc already does these itself. */
3075
3076 { NULL, NULL }
3077 };
3078
3079 /* Returns true if the current MCU supports an F5xxx series
3080 hardware multiper. */
3081
3082 bool
msp430_use_f5_series_hwmult(void)3083 msp430_use_f5_series_hwmult (void)
3084 {
3085 static const char * cached_match = NULL;
3086 static bool cached_result;
3087
3088 if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
3089 return true;
3090
3091 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3092 return false;
3093
3094 if (target_mcu == cached_match)
3095 return cached_result;
3096
3097 cached_match = target_mcu;
3098
3099 if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
3100 return cached_result = true;
3101 if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
3102 return cached_result = true;
3103 if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
3104 return cached_result = true;
3105
3106 msp430_extract_mcu_data (target_mcu);
3107
3108 if (extracted_mcu_data.name != NULL)
3109 return cached_result = extracted_mcu_data.hwmpy == 8;
3110
3111 return cached_result = false;
3112 }
3113
3114 /* Returns true if the current MCU has a second generation
3115 32-bit hardware multiplier. */
3116
3117 static bool
use_32bit_hwmult(void)3118 use_32bit_hwmult (void)
3119 {
3120 static const char * cached_match = NULL;
3121 static bool cached_result;
3122
3123 if (msp430_hwmult_type == MSP430_HWMULT_LARGE)
3124 return true;
3125
3126 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3127 return false;
3128
3129 if (target_mcu == cached_match)
3130 return cached_result;
3131
3132 cached_match = target_mcu;
3133
3134 msp430_extract_mcu_data (target_mcu);
3135 if (extracted_mcu_data.name != NULL)
3136 return cached_result = extracted_mcu_data.hwmpy == 4;
3137
3138 return cached_result = false;
3139 }
3140
3141 /* Returns true if the current MCU does not have a
3142 hardware multiplier of any kind. */
3143
3144 bool
msp430_has_hwmult(void)3145 msp430_has_hwmult (void)
3146 {
3147 static const char * cached_match = NULL;
3148 static bool cached_result;
3149
3150 if (msp430_hwmult_type == MSP430_HWMULT_NONE)
3151 return false;
3152
3153 /* TRUE for any other explicit hwmult specified. */
3154 if (msp430_hwmult_type != MSP430_HWMULT_AUTO)
3155 return true;
3156
3157 /* Now handle -mhwmult=auto. */
3158 if (target_mcu == NULL)
3159 return false;
3160
3161 if (target_mcu == cached_match)
3162 return cached_result;
3163
3164 cached_match = target_mcu;
3165
3166 msp430_extract_mcu_data (target_mcu);
3167 if (extracted_mcu_data.name != NULL)
3168 return cached_result = extracted_mcu_data.hwmpy != 0;
3169
3170 /* If we do not recognise the MCU name, we assume that it does not support
3171 any kind of hardware multiply - this is the safest assumption to make. */
3172 return cached_result = false;
3173 }
3174
3175 /* This function does the same as the default, but it will replace GCC
3176 function names with the MSPABI-specified ones. */
3177
3178 void
msp430_output_labelref(FILE * file,const char * name)3179 msp430_output_labelref (FILE *file, const char *name)
3180 {
3181 int i;
3182
3183 for (i = 0; helper_function_name_mappings[i].gcc_name; i++)
3184 if (strcmp (helper_function_name_mappings[i].gcc_name, name) == 0)
3185 {
3186 name = helper_function_name_mappings[i].ti_name;
3187 break;
3188 }
3189
3190 /* If we have been given a specific MCU name then we may be
3191 able to make use of its hardware multiply capabilities. */
3192 if (msp430_has_hwmult ())
3193 {
3194 if (strcmp ("__mspabi_mpyi", name) == 0)
3195 {
3196 if (msp430_use_f5_series_hwmult ())
3197 name = "__mulhi2_f5";
3198 else
3199 name = "__mulhi2";
3200 }
3201 else if (strcmp ("__mspabi_mpyl", name) == 0)
3202 {
3203 if (msp430_use_f5_series_hwmult ())
3204 name = "__mulsi2_f5";
3205 else if (use_32bit_hwmult ())
3206 name = "__mulsi2_hw32";
3207 else
3208 name = "__mulsi2";
3209 }
3210 }
3211
3212 if (user_label_prefix[0] != 0)
3213 fputs (user_label_prefix, file);
3214
3215 fputs (name, file);
3216 }
3217
3218 /* Common code for msp430_print_operand... */
3219
3220 static void
msp430_print_operand_raw(FILE * file,rtx op)3221 msp430_print_operand_raw (FILE * file, rtx op)
3222 {
3223 HOST_WIDE_INT i;
3224
3225 switch (GET_CODE (op))
3226 {
3227 case REG:
3228 fprintf (file, "%s", reg_names[REGNO (op)]);
3229 break;
3230
3231 case CONST_INT:
3232 i = INTVAL (op);
3233 if (TARGET_ASM_HEX)
3234 fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
3235 else
3236 fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
3237 break;
3238
3239 case CONST:
3240 case PLUS:
3241 case MINUS:
3242 case SYMBOL_REF:
3243 case LABEL_REF:
3244 output_addr_const (file, op);
3245 break;
3246
3247 default:
3248 print_rtl (file, op);
3249 break;
3250 }
3251 }
3252
3253 #undef TARGET_ASM_ALIGNED_PSI_OP
3254 #define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
3255 #undef TARGET_ASM_UNALIGNED_PSI_OP
3256 #define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
3257
3258 #undef TARGET_PRINT_OPERAND_ADDRESS
3259 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
3260
3261 /* Output to stdio stream FILE the assembler syntax for an
3262 instruction operand that is a memory reference whose address
3263 is ADDR. */
3264
3265 static void
msp430_print_operand_addr(FILE * file,machine_mode,rtx addr)3266 msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
3267 {
3268 switch (GET_CODE (addr))
3269 {
3270 case PLUS:
3271 msp430_print_operand_raw (file, XEXP (addr, 1));
3272 gcc_assert (REG_P (XEXP (addr, 0)));
3273 fprintf (file, "(%s)", reg_names[REGNO (XEXP (addr, 0))]);
3274 return;
3275
3276 case REG:
3277 fprintf (file, "@");
3278 break;
3279
3280 case POST_INC:
3281 fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
3282 return;
3283
3284 case CONST:
3285 case CONST_INT:
3286 case SYMBOL_REF:
3287 case LABEL_REF:
3288 fprintf (file, "&");
3289 break;
3290
3291 default:
3292 break;
3293 }
3294
3295 msp430_print_operand_raw (file, addr);
3296 }
3297
3298 /* We can only allow signed 15-bit indexes i.e. +/-32K. */
3299 static bool
msp430_check_index_not_high_mem(rtx op)3300 msp430_check_index_not_high_mem (rtx op)
3301 {
3302 if (CONST_INT_P (op)
3303 && IN_RANGE (INTVAL (op), HOST_WIDE_INT_M1U << 15, (1 << 15) - 1))
3304 return true;
3305 return false;
3306 }
3307
3308 /* If this returns true, we don't need a 430X insn. */
3309 static bool
msp430_check_plus_not_high_mem(rtx op)3310 msp430_check_plus_not_high_mem (rtx op)
3311 {
3312 if (GET_CODE (op) != PLUS)
3313 return false;
3314 rtx op0 = XEXP (op, 0);
3315 rtx op1 = XEXP (op, 1);
3316 if (SYMBOL_REF_P (op0)
3317 && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM)
3318 && msp430_check_index_not_high_mem (op1))
3319 return true;
3320 return false;
3321 }
3322
3323 /* Determine whether an RTX is definitely not a MEM referencing an address in
3324 the upper memory region. Returns true if we've decided the address will be
3325 in the lower memory region, or the RTX is not a MEM. Returns false
3326 otherwise.
3327 The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
3328 involving a symbol_ref here. */
3329 bool
msp430_op_not_in_high_mem(rtx op)3330 msp430_op_not_in_high_mem (rtx op)
3331 {
3332 rtx op0;
3333
3334 if (!TARGET_LARGE || !MEM_P (op))
3335 return true;
3336
3337 op0 = XEXP (op, 0);
3338
3339 if (SYMBOL_REF_P (op0) && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM))
3340 /* msp430_encode_section_info decided this mem will be in lower
3341 memory. */
3342 return true;
3343
3344 /* Check possibilites for (mem (plus)).
3345 e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2. */
3346 if (msp430_check_plus_not_high_mem (op0)
3347 || ((GET_CODE (op0) == CONST)
3348 && msp430_check_plus_not_high_mem (XEXP (op0, 0))))
3349 return true;
3350
3351 /* An absolute 16-bit address is allowed. */
3352 if ((CONST_INT_P (op0) && (IN_RANGE (INTVAL (op0), 0, (1 << 16) - 1))))
3353 return true;
3354
3355 /* Return false when undecided. */
3356 return false;
3357 }
3358
3359 #undef TARGET_PRINT_OPERAND
3360 #define TARGET_PRINT_OPERAND msp430_print_operand
3361
3362 /* A low 16-bits of int/lower of register pair
3363 B high 16-bits of int/higher of register pair
3364 C bits 32-47 of a 64-bit value/reg 3 of a DImode value
3365 D bits 48-63 of a 64-bit value/reg 4 of a DImode value
3366 H like %B (for backwards compatibility)
3367 I inverse of value
3368 J an integer without a # prefix
3369 L like %A (for backwards compatibility)
3370 O offset of the top of the stack
3371 Q like X but generates an A postfix
3372 R inverse of condition code, unsigned.
3373 X X instruction postfix in large mode
3374 Y value - 4
3375 Z value - 1
3376 b .B or .W or .A, depending upon the mode
3377 p bit position
3378 r inverse of condition code
3379 x like X but only for pointers. */
3380
3381 static void
msp430_print_operand(FILE * file,rtx op,int letter)3382 msp430_print_operand (FILE * file, rtx op, int letter)
3383 {
3384 rtx addr;
3385
3386 /* We can't use c, n, a, or l. */
3387 switch (letter)
3388 {
3389 case 'Z':
3390 gcc_assert (CONST_INT_P (op));
3391 /* Print the constant value, less one. */
3392 fprintf (file, "#%ld", INTVAL (op) - 1);
3393 return;
3394 case 'Y':
3395 gcc_assert (CONST_INT_P (op));
3396 /* Print the constant value, less four. */
3397 fprintf (file, "#%ld", INTVAL (op) - 4);
3398 return;
3399 case 'I':
3400 if (GET_CODE (op) == CONST_INT)
3401 {
3402 /* Inverse of constants */
3403 int i = INTVAL (op);
3404 fprintf (file, "%d", ~i);
3405 return;
3406 }
3407 op = XEXP (op, 0);
3408 break;
3409 case 'r': /* Conditional jump where the condition is reversed. */
3410 switch (GET_CODE (op))
3411 {
3412 case EQ: fprintf (file, "NE"); break;
3413 case NE: fprintf (file, "EQ"); break;
3414 case GEU: fprintf (file, "LO"); break;
3415 case LTU: fprintf (file, "HS"); break;
3416 case GE: fprintf (file, "L"); break;
3417 case LT: fprintf (file, "GE"); break;
3418 /* Assume these have reversed operands. */
3419 case GTU: fprintf (file, "HS"); break;
3420 case LEU: fprintf (file, "LO"); break;
3421 case GT: fprintf (file, "GE"); break;
3422 case LE: fprintf (file, "L"); break;
3423 default:
3424 msp430_print_operand_raw (file, op);
3425 break;
3426 }
3427 return;
3428 case 'R': /* Conditional jump where the operands are reversed. */
3429 switch (GET_CODE (op))
3430 {
3431 case GTU: fprintf (file, "LO"); break;
3432 case LEU: fprintf (file, "HS"); break;
3433 case GT: fprintf (file, "L"); break;
3434 case LE: fprintf (file, "GE"); break;
3435 default:
3436 msp430_print_operand_raw (file, op);
3437 break;
3438 }
3439 return;
3440 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
3441 gcc_assert (CONST_INT_P (op));
3442 fprintf (file, "#%d", 1 << INTVAL (op));
3443 return;
3444 case 'b':
3445 switch (GET_MODE (op))
3446 {
3447 case E_QImode: fprintf (file, ".B"); return;
3448 case E_HImode: fprintf (file, ".W"); return;
3449 case E_PSImode: fprintf (file, ".A"); return;
3450 case E_SImode: fprintf (file, ".A"); return;
3451 default:
3452 return;
3453 }
3454 case 'A':
3455 case 'L': /* Low half. */
3456 switch (GET_CODE (op))
3457 {
3458 case MEM:
3459 op = adjust_address (op, Pmode, 0);
3460 break;
3461 case REG:
3462 break;
3463 case CONST_INT:
3464 op = GEN_INT (INTVAL (op) & 0xffff);
3465 letter = 0;
3466 break;
3467 default:
3468 /* If you get here, figure out a test case :-) */
3469 gcc_unreachable ();
3470 }
3471 break;
3472 case 'B':
3473 case 'H': /* high half */
3474 switch (GET_CODE (op))
3475 {
3476 case MEM:
3477 /* We don't need to adjust the address for post_inc. */
3478 op = adjust_address (op, Pmode,
3479 (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 2);
3480 break;
3481 case REG:
3482 op = gen_rtx_REG (Pmode, REGNO (op) + 1);
3483 break;
3484 case CONST_INT:
3485 op = GEN_INT (INTVAL (op) >> 16);
3486 letter = 0;
3487 break;
3488 default:
3489 /* If you get here, figure out a test case :-) */
3490 gcc_unreachable ();
3491 }
3492 break;
3493 case 'C':
3494 switch (GET_CODE (op))
3495 {
3496 case MEM:
3497 op = adjust_address (op, Pmode,
3498 (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 4);
3499 break;
3500 case REG:
3501 op = gen_rtx_REG (Pmode, REGNO (op) + 2);
3502 break;
3503 case CONST_INT:
3504 op = GEN_INT ((long long) INTVAL (op) >> 32);
3505 letter = 0;
3506 break;
3507 default:
3508 /* If you get here, figure out a test case :-) */
3509 gcc_unreachable ();
3510 }
3511 break;
3512 case 'D':
3513 switch (GET_CODE (op))
3514 {
3515 case MEM:
3516 op = adjust_address (op, Pmode,
3517 (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 6);
3518 break;
3519 case REG:
3520 op = gen_rtx_REG (Pmode, REGNO (op) + 3);
3521 break;
3522 case CONST_INT:
3523 op = GEN_INT ((long long) INTVAL (op) >> 48);
3524 letter = 0;
3525 break;
3526 default:
3527 /* If you get here, figure out a test case :-) */
3528 gcc_unreachable ();
3529 }
3530 break;
3531
3532 case 'X':
3533 /* This is used to turn, for example, an ADD opcode into an ADDX
3534 opcode when we're using 20-bit addresses.
3535 This can be used for insns which have only one operand which might be
3536 a mem.
3537 If an insn has two different operands which could be memory operands,
3538 then the "Yx" constraint must be used to determine if the X suffix is
3539 required by checking both operands. */
3540 if (GET_MODE (op) == PSImode
3541 || !msp430_op_not_in_high_mem (op))
3542 fprintf (file, "X");
3543 return;
3544
3545 case 'x':
3546 /* Similarly, but only for PSImodes. BIC, and other insn patterns using
3547 the QHI mode iterator (which includes, QI, HI, and PSImode) use
3548 this. */
3549 if (GET_MODE (op) == PSImode)
3550 fprintf (file, "X");
3551 return;
3552
3553 case 'Q':
3554 /* Likewise, for BR -> BRA. */
3555 if (TARGET_LARGE)
3556 fprintf (file, "A");
3557 return;
3558
3559 case 'O':
3560 /* Computes the offset to the top of the stack for the current frame.
3561 This has to be done here rather than in, say, msp430_expand_builtin()
3562 because builtins are expanded before the frame layout is
3563 determined. */
3564 fprintf (file, "%d",
3565 msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
3566 STACK_POINTER_REGNUM)
3567 - (TARGET_LARGE ? 4 : 2));
3568 return;
3569
3570 case 'J':
3571 gcc_assert (GET_CODE (op) == CONST_INT);
3572 case 0:
3573 break;
3574 default:
3575 output_operand_lossage ("invalid operand prefix");
3576 return;
3577 }
3578
3579 switch (GET_CODE (op))
3580 {
3581 case REG:
3582 msp430_print_operand_raw (file, op);
3583 break;
3584
3585 case MEM:
3586 addr = XEXP (op, 0);
3587 msp430_print_operand_addr (file, GET_MODE (op), addr);
3588 break;
3589
3590 case CONST:
3591 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
3592 {
3593 op = XEXP (op, 0);
3594 switch (INTVAL (XEXP (op, 2)))
3595 {
3596 case 0:
3597 fprintf (file, "#lo (");
3598 msp430_print_operand_raw (file, XEXP (op, 0));
3599 fprintf (file, ")");
3600 break;
3601
3602 case 16:
3603 fprintf (file, "#hi (");
3604 msp430_print_operand_raw (file, XEXP (op, 0));
3605 fprintf (file, ")");
3606 break;
3607
3608 default:
3609 output_operand_lossage ("invalid zero extract");
3610 break;
3611 }
3612 break;
3613 }
3614 /* Fall through. */
3615 case CONST_INT:
3616 case SYMBOL_REF:
3617 case LABEL_REF:
3618 if (letter == 0)
3619 fprintf (file, "#");
3620 msp430_print_operand_raw (file, op);
3621 break;
3622
3623 case EQ: fprintf (file, "EQ"); break;
3624 case NE: fprintf (file, "NE"); break;
3625 case GEU: fprintf (file, "HS"); break;
3626 case LTU: fprintf (file, "LO"); break;
3627 case GE: fprintf (file, "GE"); break;
3628 case LT: fprintf (file, "L"); break;
3629
3630 default:
3631 print_rtl (file, op);
3632 break;
3633 }
3634 }
3635
3636
3637 /* Frame stuff. */
3638
3639 rtx
msp430_return_addr_rtx(int count)3640 msp430_return_addr_rtx (int count)
3641 {
3642 int ra_size;
3643 if (count)
3644 return NULL_RTX;
3645
3646 ra_size = TARGET_LARGE ? 4 : 2;
3647 if (crtl->args.pretend_args_size)
3648 ra_size += 2;
3649
3650 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx,
3651 GEN_INT (- ra_size)));
3652 }
3653
3654 rtx
msp430_incoming_return_addr_rtx(void)3655 msp430_incoming_return_addr_rtx (void)
3656 {
3657 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
3658 }
3659
3660 /* If the path to the MSP430-GCC support files has been found by examining
3661 an environment variable (see msp430_check_env_var_for_devices in
3662 msp430-devices.c), or -mdevices-csv-loc=, register this path as an include
3663 directory so the user can #include msp430.h without needing to specify the
3664 path to the support files with -I. */
3665 void
msp430_register_pre_includes(const char * sysroot ATTRIBUTE_UNUSED,const char * iprefix ATTRIBUTE_UNUSED,int stdinc ATTRIBUTE_UNUSED)3666 msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
3667 const char *iprefix ATTRIBUTE_UNUSED,
3668 int stdinc ATTRIBUTE_UNUSED)
3669 {
3670 char *include_dir;
3671 if (msp430_devices_csv_loc)
3672 include_dir = xstrdup (msp430_devices_csv_loc);
3673 else if (msp430_check_env_var_for_devices (&include_dir))
3674 return;
3675 include_dir = msp430_dirname (include_dir);
3676
3677 include_dir = update_path (include_dir, "");
3678 add_path (include_dir, INC_SYSTEM, false, false);
3679 }
3680
3681 /* Instruction generation stuff. */
3682
3683 /* Generate a sequence of instructions to sign-extend an HI
3684 value into an SI value. Handles the tricky case where
3685 we are overwriting the destination. */
3686
3687 const char *
msp430x_extendhisi(rtx * operands)3688 msp430x_extendhisi (rtx * operands)
3689 {
3690 if (REGNO (operands[0]) == REGNO (operands[1]))
3691 /* Low word of dest == source word. 8-byte sequence. */
3692 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0";
3693
3694 if (! msp430x)
3695 /* Note: This sequence is approximately the same length as invoking a helper
3696 function to perform the sign-extension, as in:
3697
3698 MOV.W %1, %L0
3699 MOV.W %1, r12
3700 CALL __mspabi_srai_15
3701 MOV.W r12, %H0
3702
3703 but this version does not involve any function calls or using argument
3704 registers, so it reduces register pressure. 10-byte sequence. */
3705 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 "
3706 "{ INV.W\t%H0, %H0";
3707
3708 if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
3709 /* High word of dest == source word. 6-byte sequence. */
3710 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0";
3711
3712 /* No overlap between dest and source. 8-byte sequence. */
3713 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0";
3714 }
3715
3716 /* Likewise for logical right shifts. */
3717 const char *
msp430x_logical_shift_right(rtx amount)3718 msp430x_logical_shift_right (rtx amount)
3719 {
3720 /* The MSP430X's logical right shift instruction - RRUM - does
3721 not use an extension word, so we cannot encode a repeat count.
3722 Try various alternatives to work around this. If the count
3723 is in a register we are stuck, hence the assert. */
3724 gcc_assert (CONST_INT_P (amount));
3725
3726 if (INTVAL (amount) <= 0
3727 || INTVAL (amount) >= 16)
3728 return "# nop logical shift.";
3729
3730 if (INTVAL (amount) > 0
3731 && INTVAL (amount) < 5)
3732 return "rrum.w\t%2, %0"; /* Two bytes. */
3733
3734 if (INTVAL (amount) > 4
3735 && INTVAL (amount) < 9)
3736 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
3737
3738 /* First we logically shift right by one. Now we know
3739 that the top bit is zero and we can use the arithmetic
3740 right shift instruction to perform the rest of the shift. */
3741 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */
3742 }
3743
3744 /* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */
3745
3746 #undef TARGET_CAN_CHANGE_MODE_CLASS
3747 #define TARGET_CAN_CHANGE_MODE_CLASS msp430_can_change_mode_class
3748
3749 static bool
msp430_can_change_mode_class(machine_mode from,machine_mode to,reg_class_t)3750 msp430_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t)
3751 {
3752 if ((to == PSImode && from == SImode)
3753 || (to == SImode && from == PSImode)
3754 || (to == DImode && from == PSImode)
3755 || (to == PSImode && from == DImode))
3756 return false;
3757 return true;
3758 }
3759
3760 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
3761 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
3762
3763 struct gcc_target targetm = TARGET_INITIALIZER;
3764
3765 #include "gt-msp430.h"
3766