aix: Alias -m64 to -maix64 and -m32 to -maix32.
[official-gcc.git] / gcc / config / msp430 / msp430.c
blob581e051f68f79891a5d4cfd741bae995070f1e01
1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2021 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
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.
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.
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/>. */
21 #define IN_TARGET_CODE 1
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 #include "insn-config.h"
53 #include "insn-attr.h"
54 #include "recog.h"
56 /* This file should be included last. */
57 #include "target-def.h"
60 static void msp430_compute_frame_info (void);
61 static bool msp430_use_16bit_hwmult (void);
62 static bool msp430_use_32bit_hwmult (void);
63 static bool use_helper_for_const_shift (machine_mode mode, HOST_WIDE_INT amt);
67 /* Run-time Target Specification. */
69 bool msp430x = true;
71 struct GTY(()) machine_function
73 /* If set, the rest of the fields have been computed. */
74 int computed;
75 /* Which registers need to be saved in the pro/epilogue. */
76 int need_to_save[FIRST_PSEUDO_REGISTER];
78 /* These fields describe the frame layout... */
79 /* arg pointer */
80 /* 2/4 bytes for saved PC */
81 int framesize_regs;
82 /* frame pointer */
83 int framesize_locals;
84 int framesize_outgoing;
85 /* stack pointer */
86 int framesize;
88 /* How much we adjust the stack when returning from an exception
89 handler. */
90 rtx eh_stack_adjust;
93 /* This is our init_machine_status, as set in
94 msp430_option_override. */
95 static struct machine_function *
96 msp430_init_machine_status (void)
98 struct machine_function *m;
100 m = ggc_cleared_alloc<machine_function> ();
102 return m;
105 #undef TARGET_OPTION_OVERRIDE
106 #define TARGET_OPTION_OVERRIDE msp430_option_override
108 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
109 If a specific MCU has not been selected then return a generic symbol
110 instead. */
112 const char *
113 msp430_mcu_name (void)
115 if (target_mcu)
117 msp430_extract_mcu_data (target_mcu);
118 unsigned int i;
119 unsigned int start_upper;
120 unsigned int end_upper;
121 static char mcu_name[64];
123 /* The 'i' in the device name symbol for msp430i* devices must be lower
124 case, to match the expected symbol in msp430.h. */
125 if (strncmp (target_mcu, "msp430i", 7) == 0)
127 snprintf (mcu_name, sizeof (mcu_name) - 1, "__MSP430i%s__",
128 target_mcu + 7);
129 start_upper = 9;
131 else
133 snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu);
134 start_upper = 2;
136 end_upper = strlen (mcu_name) - 2;
137 for (i = start_upper; i < end_upper; i++)
138 mcu_name[i] = TOUPPER (mcu_name[i]);
139 return mcu_name;
142 return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
145 static const char *
146 hwmult_name (unsigned int val)
148 switch (val)
150 case 0: return "none";
151 case 1: return "16-bit";
152 case 2: return "16-bit";
153 case 4: return "32-bit";
154 case 8: return "32-bit (5xx)";
155 default: gcc_unreachable ();
159 static void
160 msp430_option_override (void)
162 /* The MSP430 architecture can safely dereference a NULL pointer. In fact,
163 there are memory mapped registers there. */
164 flag_delete_null_pointer_checks = 0;
166 init_machine_status = msp430_init_machine_status;
168 msp430x = target_cpu >= MSP430_CPU_MSP430X_DEFAULT;
170 if (target_mcu)
172 msp430_extract_mcu_data (target_mcu);
174 if (extracted_mcu_data.name != NULL)
176 bool xisa = extracted_mcu_data.revision >= 1;
178 if (msp430_warn_mcu)
180 if (target_cpu != MSP430_CPU_MSP430X_DEFAULT && msp430x != xisa)
181 warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
182 "is set to %s",
183 target_mcu, xisa ? "430X" : "430",
184 msp430x ? "430X" : "430");
186 if (extracted_mcu_data.hwmpy == 0
187 && msp430_hwmult_type != MSP430_HWMULT_AUTO
188 && msp430_hwmult_type != MSP430_HWMULT_NONE)
189 warning (0, "MCU %qs does not have hardware multiply "
190 "support, but %<-mhwmult%> is set to %s",
191 target_mcu,
192 msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit"
193 : msp430_hwmult_type == MSP430_HWMULT_LARGE
194 ? "32-bit" : "f5series");
195 else if (msp430_hwmult_type == MSP430_HWMULT_SMALL
196 && extracted_mcu_data.hwmpy != 1
197 && extracted_mcu_data.hwmpy != 2)
198 warning (0, "MCU %qs supports %s hardware multiply, "
199 "but %<-mhwmult%> is set to 16-bit",
200 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
201 else if (msp430_hwmult_type == MSP430_HWMULT_LARGE
202 && extracted_mcu_data.hwmpy != 4)
203 warning (0, "MCU %qs supports %s hardware multiply, "
204 "but %<-mhwmult%> is set to 32-bit",
205 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
206 else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES
207 && extracted_mcu_data.hwmpy != 8)
208 warning (0, "MCU %qs supports %s hardware multiply, "
209 "but %<-mhwmult%> is set to f5series",
210 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
212 /* Only override the default setting with the extracted ISA value if
213 the user has not passed -mcpu=. */
214 if (target_cpu == MSP430_CPU_MSP430X_DEFAULT)
215 msp430x = xisa;
217 else
219 if (msp430_hwmult_type == MSP430_HWMULT_AUTO)
221 if (msp430_warn_mcu)
223 if (target_cpu == MSP430_CPU_MSP430X_DEFAULT)
224 warning (0,
225 "Unrecognized MCU name %qs, assuming that it is "
226 "just a MSP430X 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);
238 msp430_hwmult_type = MSP430_HWMULT_NONE;
240 else if (target_cpu == MSP430_CPU_MSP430X_DEFAULT)
242 if (msp430_warn_mcu)
243 warning (0,
244 "Unrecognized MCU name %qs, assuming that it just "
245 "supports the MSP430X ISA.\nUse the %<-mcpu%> option "
246 "to set the ISA explicitly.",
247 target_mcu);
249 else if (msp430_warn_mcu)
250 warning (0, "Unrecognized MCU name %qs.", target_mcu);
254 if (TARGET_LARGE && !msp430x)
255 error ("%<-mlarge%> requires a 430X-compatible %<-mmcu=%>");
257 if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_EITHER)
258 error ("%<-mcode-region=either%> requires the large memory model "
259 "(%<-mlarge%>)");
260 else if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_UPPER)
261 error ("%<-mcode-region=upper%> requires the large memory model "
262 "(%<-mlarge%>)");
264 if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_EITHER)
265 error ("%<-mdata-region=either%> requires the large memory model "
266 "(%<-mlarge%>)");
267 else if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_UPPER)
268 error ("%<-mdata-region=upper%> requires the large memory model "
269 "(%<-mlarge%>)");
271 if (flag_exceptions || flag_non_call_exceptions
272 || flag_unwind_tables || flag_asynchronous_unwind_tables)
273 flag_omit_frame_pointer = false;
274 else
275 flag_omit_frame_pointer = true;
277 /* This is a hack to work around a problem with the newlib build
278 mechanism. Newlib always appends CFLAGS to the end of the GCC
279 command line and always sets -O2 in CFLAGS. Thus it is not
280 possible to build newlib with -Os enabled. Until now... */
281 if (TARGET_OPT_SPACE && optimize < 3)
282 optimize_size = 1;
284 #if !DEFAULT_USE_CXA_ATEXIT
285 /* For some configurations, we use atexit () instead of __cxa_atexit () by
286 default to save on code size and remove the declaration of __dso_handle
287 from the CRT library.
288 Configuring GCC with --enable-__cxa-atexit re-enables it by defining
289 DEFAULT_USE_CXA_ATEXIT to 1. */
290 if (flag_use_cxa_atexit)
291 error ("%<-fuse-cxa-atexit%> is not supported for msp430-elf");
292 #endif
294 #ifndef HAVE_NEWLIB_NANO_FORMATTED_IO
295 if (TARGET_TINY_PRINTF)
296 error ("GCC must be configured with %<--enable-newlib-nano-formatted-io%> "
297 "to use %<-mtiny-printf%>");
298 #endif
301 #undef TARGET_SCALAR_MODE_SUPPORTED_P
302 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
304 static bool
305 msp430_scalar_mode_supported_p (scalar_mode m)
307 if (m == PSImode && msp430x)
308 return true;
309 #if 0
310 if (m == TImode)
311 return true;
312 #endif
313 return default_scalar_mode_supported_p (m);
318 /* Storage Layout */
320 #undef TARGET_MS_BITFIELD_LAYOUT_P
321 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
323 bool
324 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
326 return false;
331 /* Register Usage */
333 #undef TARGET_HARD_REGNO_NREGS
334 #define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs
336 static unsigned int
337 msp430_hard_regno_nregs (unsigned int, machine_mode mode)
339 if (mode == PSImode && msp430x)
340 return 1;
341 if (mode == CPSImode && msp430x)
342 return 2;
343 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
344 / UNITS_PER_WORD);
347 /* subreg_get_info correctly handles PSImode registers, so defining
348 HARD_REGNO_NREGS_HAS_PADDING and HARD_REGNO_NREGS_WITH_PADDING
349 has no effect. */
351 #undef TARGET_HARD_REGNO_MODE_OK
352 #define TARGET_HARD_REGNO_MODE_OK msp430_hard_regno_mode_ok
354 static bool
355 msp430_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
357 return regno <= (ARG_POINTER_REGNUM
358 - (unsigned int) msp430_hard_regno_nregs (regno, mode));
361 #undef TARGET_MODES_TIEABLE_P
362 #define TARGET_MODES_TIEABLE_P msp430_modes_tieable_p
364 static bool
365 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2)
367 if ((mode1 == PSImode || mode2 == SImode)
368 || (mode1 == SImode || mode2 == PSImode))
369 return false;
371 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
372 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
373 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
374 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
377 #undef TARGET_FRAME_POINTER_REQUIRED
378 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
380 static bool
381 msp430_frame_pointer_required (void)
383 return false;
386 #undef TARGET_CAN_ELIMINATE
387 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
389 static bool
390 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
391 const int to_reg ATTRIBUTE_UNUSED)
393 return true;
396 /* Implements INITIAL_ELIMINATION_OFFSET. */
398 msp430_initial_elimination_offset (int from, int to)
400 int rv = 0; /* As if arg to arg. */
402 msp430_compute_frame_info ();
404 switch (to)
406 case STACK_POINTER_REGNUM:
407 rv += cfun->machine->framesize_outgoing;
408 rv += cfun->machine->framesize_locals;
409 /* Fall through. */
410 case FRAME_POINTER_REGNUM:
411 rv += cfun->machine->framesize_regs;
412 /* Allow for the saved return address. */
413 rv += (TARGET_LARGE ? 4 : 2);
414 /* NB/ No need to allow for crtl->args.pretend_args_size.
415 GCC does that for us. */
416 break;
417 default:
418 gcc_unreachable ();
421 switch (from)
423 case FRAME_POINTER_REGNUM:
424 /* Allow for the fall through above. */
425 rv -= (TARGET_LARGE ? 4 : 2);
426 rv -= cfun->machine->framesize_regs;
427 case ARG_POINTER_REGNUM:
428 break;
429 default:
430 gcc_unreachable ();
433 return rv;
436 /* Named Address Space support */
439 /* Return the appropriate mode for a named address pointer. */
440 #undef TARGET_ADDR_SPACE_POINTER_MODE
441 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
442 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
443 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
445 static scalar_int_mode
446 msp430_addr_space_pointer_mode (addr_space_t addrspace)
448 switch (addrspace)
450 default:
451 case ADDR_SPACE_GENERIC:
452 return Pmode;
453 case ADDR_SPACE_NEAR:
454 return HImode;
455 case ADDR_SPACE_FAR:
456 return PSImode;
460 /* Function pointers are stored in unwind_word sized
461 variables, so make sure that unwind_word is big enough. */
462 #undef TARGET_UNWIND_WORD_MODE
463 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
465 static scalar_int_mode
466 msp430_unwind_word_mode (void)
468 /* This needs to match msp430_init_dwarf_reg_sizes_extra (below). */
469 return msp430x ? PSImode : HImode;
472 /* Determine if one named address space is a subset of another. */
473 #undef TARGET_ADDR_SPACE_SUBSET_P
474 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
475 static bool
476 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
478 if (subset == superset)
479 return true;
480 else
481 return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR);
484 #undef TARGET_ADDR_SPACE_CONVERT
485 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
486 /* Convert from one address space to another. */
487 static rtx
488 msp430_addr_space_convert (rtx op, tree from_type, tree to_type)
490 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
491 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
492 rtx result;
494 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
496 /* This is unpredictable, as we're truncating off usable address
497 bits. */
499 if (CONSTANT_P (op))
500 return gen_rtx_CONST (HImode, op);
502 result = gen_reg_rtx (HImode);
503 emit_insn (gen_truncpsihi2 (result, op));
504 return result;
506 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
508 /* This always works. */
510 if (CONSTANT_P (op))
511 return gen_rtx_CONST (PSImode, op);
513 result = gen_reg_rtx (PSImode);
514 emit_insn (gen_zero_extendhipsi2 (result, op));
515 return result;
517 else
518 gcc_unreachable ();
521 /* Stack Layout and Calling Conventions. */
523 /* For each function, we list the gcc version and the TI version on
524 each line, where we're converting the function names. */
525 static char const * const special_convention_function_names[] =
527 "__muldi3", "__mspabi_mpyll",
528 "__udivdi3", "__mspabi_divull",
529 "__umoddi3", "__mspabi_remull",
530 "__divdi3", "__mspabi_divlli",
531 "__moddi3", "__mspabi_remlli",
532 "__mspabi_srall",
533 "__mspabi_srlll",
534 "__mspabi_sllll",
535 "__adddf3", "__mspabi_addd",
536 "__subdf3", "__mspabi_subd",
537 "__muldf3", "__mspabi_mpyd",
538 "__divdf3", "__mspabi_divd",
539 "__mspabi_cmpd",
540 NULL
543 /* TRUE if the function passed is a "speical" function. Special
544 functions pass two DImode parameters in registers. */
545 static bool
546 msp430_special_register_convention_p (const char *name)
548 int i;
550 for (i = 0; special_convention_function_names[i]; i++)
551 if (!strcmp (name, special_convention_function_names[i]))
552 return true;
554 return false;
557 #undef TARGET_FUNCTION_VALUE_REGNO_P
558 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
560 bool
561 msp430_function_value_regno_p (unsigned int regno)
563 return regno == 12;
567 #undef TARGET_FUNCTION_VALUE
568 #define TARGET_FUNCTION_VALUE msp430_function_value
571 msp430_function_value (const_tree ret_type,
572 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
573 bool outgoing ATTRIBUTE_UNUSED)
575 return gen_rtx_REG (TYPE_MODE (ret_type), 12);
578 #undef TARGET_LIBCALL_VALUE
579 #define TARGET_LIBCALL_VALUE msp430_libcall_value
582 msp430_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
584 return gen_rtx_REG (mode, 12);
587 /* Implements INIT_CUMULATIVE_ARGS. */
588 void
589 msp430_init_cumulative_args (CUMULATIVE_ARGS *ca,
590 tree fntype ATTRIBUTE_UNUSED,
591 rtx libname ATTRIBUTE_UNUSED,
592 tree fndecl ATTRIBUTE_UNUSED,
593 int n_named_args ATTRIBUTE_UNUSED)
595 const char *fname;
596 memset (ca, 0, sizeof(*ca));
598 ca->can_split = 1;
600 if (fndecl)
601 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
602 else if (libname)
603 fname = XSTR (libname, 0);
604 else
605 fname = NULL;
607 if (fname && msp430_special_register_convention_p (fname))
608 ca->special_p = 1;
611 /* Helper function for argument passing; this function is the common
612 code that determines where an argument will be passed. */
613 static void
614 msp430_evaluate_arg (cumulative_args_t cap,
615 machine_mode mode,
616 const_tree type ATTRIBUTE_UNUSED,
617 bool named)
619 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
620 int nregs = GET_MODE_SIZE (mode);
621 int i;
623 ca->reg_count = 0;
624 ca->mem_count = 0;
626 if (!named)
627 return;
629 if (mode == PSImode)
630 nregs = 1;
631 else
632 nregs = (nregs + 1) / 2;
634 if (ca->special_p)
636 /* Function is passed two DImode operands, in R8:R11 and
637 R12:15. */
638 ca->start_reg = 8;
639 ca->reg_count = 4;
640 return;
643 switch (nregs)
645 case 1:
646 for (i = 0; i < 4; i++)
647 if (!ca->reg_used[i])
649 ca->reg_count = 1;
650 ca->start_reg = CA_FIRST_REG + i;
651 return;
653 break;
654 case 2:
655 for (i = 0; i < 3; i++)
656 if (!ca->reg_used[i] && !ca->reg_used[i + 1])
658 ca->reg_count = 2;
659 ca->start_reg = CA_FIRST_REG + i;
660 return;
662 if (!ca->reg_used[3] && ca->can_split)
664 ca->reg_count = 1;
665 ca->mem_count = 2;
666 ca->start_reg = CA_FIRST_REG + 3;
667 return;
669 break;
670 case 3:
671 case 4:
672 ca->can_split = 0;
673 if (!ca->reg_used[0]
674 && !ca->reg_used[1]
675 && !ca->reg_used[2]
676 && !ca->reg_used[3])
678 ca->reg_count = 4;
679 ca->start_reg = CA_FIRST_REG;
680 return;
682 break;
686 #undef TARGET_PROMOTE_PROTOTYPES
687 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
689 bool
690 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
692 return false;
695 #undef TARGET_FUNCTION_ARG
696 #define TARGET_FUNCTION_ARG msp430_function_arg
699 msp430_function_arg (cumulative_args_t cap,
700 const function_arg_info &arg)
702 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
704 msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
706 if (ca->reg_count)
707 return gen_rtx_REG (arg.mode, ca->start_reg);
709 return 0;
712 #undef TARGET_ARG_PARTIAL_BYTES
713 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
716 msp430_arg_partial_bytes (cumulative_args_t cap, const function_arg_info &arg)
718 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
720 msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
722 if (ca->reg_count && ca->mem_count)
723 return ca->reg_count * UNITS_PER_WORD;
725 return 0;
728 #undef TARGET_PASS_BY_REFERENCE
729 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
731 static bool
732 msp430_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
734 return (arg.mode == BLKmode
735 || (arg.type && TREE_CODE (arg.type) == RECORD_TYPE)
736 || (arg.type && TREE_CODE (arg.type) == UNION_TYPE));
739 #undef TARGET_CALLEE_COPIES
740 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_arg_info_true
742 #undef TARGET_FUNCTION_ARG_ADVANCE
743 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
745 void
746 msp430_function_arg_advance (cumulative_args_t cap,
747 const function_arg_info &arg)
749 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
750 int i;
752 msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
754 if (ca->start_reg >= CA_FIRST_REG)
755 for (i = 0; i < ca->reg_count; i ++)
756 ca->reg_used[i + ca->start_reg - CA_FIRST_REG] = 1;
758 ca->special_p = 0;
761 #undef TARGET_FUNCTION_ARG_BOUNDARY
762 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
764 static unsigned int
765 msp430_function_arg_boundary (machine_mode mode, const_tree type)
767 if (mode == BLKmode
768 && int_size_in_bytes (type) > 1)
769 return 16;
770 if (GET_MODE_BITSIZE (mode) > 8)
771 return 16;
772 return 8;
775 #undef TARGET_RETURN_IN_MEMORY
776 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
778 static bool
779 msp430_return_in_memory (const_tree ret_type,
780 const_tree fntype ATTRIBUTE_UNUSED)
782 machine_mode mode = TYPE_MODE (ret_type);
784 if (mode == BLKmode
785 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE)
786 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE))
787 return true;
789 if (GET_MODE_SIZE (mode) > 8)
790 return true;
792 return false;
795 #undef TARGET_GET_RAW_ARG_MODE
796 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
798 static fixed_size_mode
799 msp430_get_raw_arg_mode (int regno)
801 return as_a <fixed_size_mode> (regno == ARG_POINTER_REGNUM
802 ? VOIDmode : Pmode);
805 #undef TARGET_GET_RAW_RESULT_MODE
806 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
808 static fixed_size_mode
809 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
811 return Pmode;
814 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
815 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
817 #include "gimplify.h"
819 static tree
820 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
821 gimple_seq *post_p)
823 tree addr, t, type_size, rounded_size, valist_tmp;
824 unsigned HOST_WIDE_INT align, boundary;
825 bool indirect;
827 indirect = pass_va_arg_by_reference (type);
828 if (indirect)
829 type = build_pointer_type (type);
831 align = PARM_BOUNDARY / BITS_PER_UNIT;
832 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
834 /* When we align parameter on stack for caller, if the parameter
835 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
836 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
837 here with caller. */
838 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
839 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
841 boundary /= BITS_PER_UNIT;
843 /* Hoist the valist value into a temporary for the moment. */
844 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
846 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
847 requires greater alignment, we must perform dynamic alignment. */
848 if (boundary > align
849 && !integer_zerop (TYPE_SIZE (type)))
851 /* FIXME: This is where this function diverts from targhooks.c:
852 std_gimplify_va_arg_expr(). It works, but I do not know why... */
853 if (! POINTER_TYPE_P (type))
855 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
856 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
857 gimplify_and_add (t, pre_p);
859 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
860 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
861 valist_tmp,
862 build_int_cst (TREE_TYPE (valist),
863 -boundary)));
864 gimplify_and_add (t, pre_p);
867 else
868 boundary = align;
870 /* If the actual alignment is less than the alignment of the type,
871 adjust the type accordingly so that we don't assume strict alignment
872 when dereferencing the pointer. */
873 boundary *= BITS_PER_UNIT;
874 if (boundary < TYPE_ALIGN (type))
876 type = build_variant_type_copy (type);
877 SET_TYPE_ALIGN (type, boundary);
880 /* Compute the rounded size of the type. */
881 type_size = size_in_bytes (type);
882 rounded_size = round_up (type_size, align);
884 /* Reduce rounded_size so it's sharable with the postqueue. */
885 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
887 /* Get AP. */
888 addr = valist_tmp;
890 /* Compute new value for AP. */
891 t = fold_build_pointer_plus (valist_tmp, rounded_size);
892 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
893 gimplify_and_add (t, pre_p);
895 addr = fold_convert (build_pointer_type (type), addr);
897 if (indirect)
898 addr = build_va_arg_indirect_ref (addr);
900 addr = build_va_arg_indirect_ref (addr);
902 return addr;
905 #undef TARGET_LRA_P
906 #define TARGET_LRA_P hook_bool_void_false
908 /* Addressing Modes */
910 #undef TARGET_LEGITIMATE_ADDRESS_P
911 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
913 static bool
914 reg_ok_for_addr (rtx r, bool strict)
916 int rn = REGNO (r);
918 if (strict && rn >= FIRST_PSEUDO_REGISTER)
919 rn = reg_renumber[rn];
920 if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
921 return true;
922 if (!strict)
923 return true;
924 return false;
927 bool
928 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
929 rtx x ATTRIBUTE_UNUSED,
930 bool strict ATTRIBUTE_UNUSED)
932 switch (GET_CODE (x))
934 case MEM:
935 return false;
937 case PLUS:
938 case POST_INC:
939 if (REG_P (XEXP (x, 0)))
941 if (GET_MODE (x) != GET_MODE (XEXP (x, 0)))
942 return false;
943 if (!reg_ok_for_addr (XEXP (x, 0), strict))
944 return false;
945 if (GET_CODE (x) == POST_INC)
946 /* At this point, if the original rtx was a post_inc, we don't have
947 anything further to check. */
948 return true;
949 switch (GET_CODE (XEXP (x, 1)))
951 case CONST:
952 case SYMBOL_REF:
953 case CONST_INT:
954 return true;
955 default:
956 return false;
959 return false;
961 case REG:
962 if (!reg_ok_for_addr (x, strict))
963 return false;
964 /* FALLTHRU */
965 case CONST:
966 case SYMBOL_REF:
967 case CONST_INT:
968 return true;
970 default:
971 return false;
975 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
976 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
977 msp430_addr_space_legitimate_address_p
979 bool
980 msp430_addr_space_legitimate_address_p (machine_mode mode,
981 rtx x,
982 bool strict,
983 addr_space_t as ATTRIBUTE_UNUSED)
985 return msp430_legitimate_address_p (mode, x, strict);
988 #undef TARGET_ASM_INTEGER
989 #define TARGET_ASM_INTEGER msp430_asm_integer
990 static bool
991 msp430_asm_integer (rtx x, unsigned int size, int aligned_p)
993 int c = GET_CODE (x);
995 if (size == 3 && GET_MODE (x) == PSImode)
996 size = 4;
998 switch (size)
1000 case 4:
1001 if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT
1002 || c == PLUS || c == MINUS)
1004 fprintf (asm_out_file, "\t.long\t");
1005 output_addr_const (asm_out_file, x);
1006 fputc ('\n', asm_out_file);
1007 return true;
1009 break;
1011 return default_assemble_integer (x, size, aligned_p);
1014 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1015 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
1016 static bool
1017 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
1019 debug_rtx (x);
1020 return false;
1023 #undef TARGET_LEGITIMATE_CONSTANT_P
1024 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1026 static bool
1027 msp430_legitimate_constant (machine_mode mode, rtx x)
1029 return ! CONST_INT_P (x)
1030 || mode != PSImode
1031 /* GCC does not know the width of the PSImode, so make
1032 sure that it does not try to use a constant value that
1033 is out of range. */
1034 || (INTVAL (x) < (1 << 20)
1035 && INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20));
1039 /* Describing Relative Costs of Operations
1040 To model the cost of an instruction, use the number of cycles when
1041 optimizing for speed, and the number of words when optimizing for size.
1042 The cheapest instruction will execute in one cycle and cost one word.
1043 The cycle and size costs correspond to 430 ISA instructions, not 430X
1044 instructions or 430X "address" instructions. The relative costs of 430X
1045 instructions is accurately modeled with the 430 costs. The relative costs
1046 of some "address" instructions can differ, but these are not yet handled.
1047 Adding support for this could improve performance/code size. */
1049 struct single_op_cost
1051 const int reg;
1052 /* Indirect register (@Rn) or indirect autoincrement (@Rn+). */
1053 const int ind;
1054 const int mem;
1057 static const struct single_op_cost cycle_cost_single_op =
1059 1, 3, 4
1062 static const struct single_op_cost size_cost_single_op =
1064 1, 1, 2
1067 /* When the destination of an insn is memory, the cost is always the same
1068 regardless of whether that memory is accessed using indirect register,
1069 indexed or absolute addressing.
1070 When the source operand is memory, indirect register and post-increment have
1071 the same cost, which is lower than indexed and absolute, which also have
1072 the same cost. */
1073 struct double_op_cost
1075 /* Source operand is a register. */
1076 const int r2r;
1077 const int r2pc;
1078 const int r2m;
1080 /* Source operand is memory, using indirect register (@Rn) or indirect
1081 autoincrement (@Rn+) addressing modes. */
1082 const int ind2r;
1083 const int ind2pc;
1084 const int ind2m;
1086 /* Source operand is an immediate. */
1087 const int imm2r;
1088 const int imm2pc;
1089 const int imm2m;
1091 /* Source operand is memory, using indexed (x(Rn)) or absolute (&ADDR)
1092 addressing modes. */
1093 const int mem2r;
1094 const int mem2pc;
1095 const int mem2m;
1098 /* These structures describe the cost of MOV, BIT and CMP instructions, in terms
1099 of clock cycles or words. */
1100 static const struct double_op_cost cycle_cost_double_op_mov =
1102 1, 3, 3,
1103 2, 4, 4,
1104 2, 3, 4,
1105 3, 5, 5
1108 /* Cycle count when memory is the destination operand is one larger than above
1109 for instructions that aren't MOV, BIT or CMP. */
1110 static const struct double_op_cost cycle_cost_double_op =
1112 1, 3, 4,
1113 2, 4, 5,
1114 2, 3, 5,
1115 3, 5, 6
1118 static const struct double_op_cost size_cost_double_op =
1120 1, 1, 2,
1121 1, 1, 2,
1122 2, 2, 3,
1123 2, 2, 3
1126 struct msp430_multlib_costs
1128 const int mulhi;
1129 const int mulsi;
1130 const int muldi;
1133 /* There is no precise size cost when using libcalls, instead it is disparaged
1134 relative to other instructions.
1135 The cycle costs are from the CALL to the RET, inclusive.
1136 FIXME muldi cost is not accurate. */
1137 static const struct msp430_multlib_costs cycle_cost_multlib_32bit =
1139 27, 33, 66
1142 /* 32bit multiply takes a few more instructions on 16bit hwmult. */
1143 static const struct msp430_multlib_costs cycle_cost_multlib_16bit =
1145 27, 42, 66
1148 /* TARGET_REGISTER_MOVE_COST
1149 There is only one class of general-purpose, non-fixed registers, and the
1150 relative cost of moving data between them is always the same.
1151 Therefore, the default of 2 is optimal. */
1153 #undef TARGET_MEMORY_MOVE_COST
1154 #define TARGET_MEMORY_MOVE_COST msp430_memory_move_cost
1156 /* Return the cost of moving data between registers and memory.
1157 The returned cost must be relative to the default TARGET_REGISTER_MOVE_COST
1158 of 2.
1159 IN is false if the value is to be written to memory. */
1160 static int
1161 msp430_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
1162 reg_class_t rclass ATTRIBUTE_UNUSED,
1163 bool in)
1165 int cost;
1166 const struct double_op_cost *cost_p;
1167 /* Optimize with a code size focus by default, unless -O2 or above is
1168 specified. */
1169 bool speed = (!optimize_size && optimize >= 2);
1171 cost_p = (speed ? &cycle_cost_double_op_mov : &size_cost_double_op);
1173 if (in)
1174 /* Reading from memory using indirect addressing is assumed to be the more
1175 common case. */
1176 cost = cost_p->ind2r;
1177 else
1178 cost = cost_p->r2m;
1180 /* All register to register moves cost 1 cycle or 1 word, so multiply by 2
1181 to get the costs relative to TARGET_REGISTER_MOVE_COST of 2. */
1182 return 2 * cost;
1185 /* For X, which must be a MEM RTX, return TRUE if it is an indirect memory
1186 reference, @Rn or @Rn+. */
1187 static bool
1188 msp430_is_mem_indirect (rtx x)
1190 gcc_assert (GET_CODE (x) == MEM);
1191 rtx op0 = XEXP (x, 0);
1192 return (GET_CODE (op0) == REG || GET_CODE (op0) == POST_INC);
1195 /* Costs of MSP430 instructions are generally based on the addressing mode
1196 combination of the source and destination operands.
1197 Given source operand SRC (which may be NULL to indicate a single-operand
1198 instruction) and destination operand DST return the cost of this
1199 expression. */
1200 static int
1201 msp430_costs (rtx src, rtx dst, bool speed, rtx outer_rtx)
1203 enum rtx_code src_code = GET_CODE (src);
1204 enum rtx_code dst_code = GET_CODE (dst);
1205 enum rtx_code outer_code = GET_CODE (outer_rtx);
1206 machine_mode outer_mode = GET_MODE (outer_rtx);
1207 const struct double_op_cost *cost_p;
1208 cost_p = (speed ? &cycle_cost_double_op : &size_cost_double_op);
1210 if (outer_code == TRUNCATE
1211 && (outer_mode == QImode
1212 || outer_mode == HImode
1213 || outer_mode == PSImode))
1214 /* Truncation to these modes is normally free as a side effect of the
1215 instructions themselves. */
1216 return 0;
1218 if (dst_code == SYMBOL_REF
1219 || dst_code == LABEL_REF
1220 || dst_code == CONST_INT)
1221 /* Catch RTX like (minus (const_int 0) (reg)) but don't add any cost. */
1222 return 0;
1224 switch (src_code)
1226 case REG:
1227 return (dst_code == REG ? cost_p->r2r
1228 : (dst_code == PC ? cost_p->r2pc : cost_p->r2m));
1230 case CONST_INT:
1231 case SYMBOL_REF:
1232 case LABEL_REF:
1233 case CONST:
1234 return (dst_code == REG ? cost_p->imm2r
1235 : (dst_code == PC ? cost_p->imm2pc : cost_p->imm2m));
1238 case MEM:
1239 if (msp430_is_mem_indirect (src))
1240 return (dst_code == REG ? cost_p->ind2r : (dst_code == PC
1241 ? cost_p->ind2pc
1242 : cost_p->ind2m));
1243 else
1244 return (dst_code == REG ? cost_p->mem2r : (dst_code == PC
1245 ? cost_p->mem2pc
1246 : cost_p->mem2m));
1247 default:
1248 return cost_p->mem2m;
1252 /* Given source operand SRC and destination operand DST from the shift or
1253 rotate RTX OUTER_RTX, return the cost of performing that shift, assuming
1254 optimization for speed when SPEED is true. */
1255 static int
1256 msp430_shift_costs (rtx src, rtx dst, bool speed, rtx outer_rtx)
1258 int amt;
1259 enum rtx_code src_code = GET_CODE (src);
1260 enum rtx_code dst_code = GET_CODE (dst);
1261 const struct single_op_cost *cost_p;
1263 cost_p = (speed ? &cycle_cost_single_op : &size_cost_single_op);
1265 if (src_code != CONST_INT)
1266 /* The size or speed cost when the shift amount is unknown cannot be
1267 accurately calculated, so just disparage it slightly. */
1268 return 2 * msp430_costs (src, dst, speed, outer_rtx);
1270 if (use_helper_for_const_shift (GET_MODE (outer_rtx), amt = INTVAL (src)))
1272 /* GCC sometimes tries to perform shifts in some very inventive ways,
1273 resulting in much larger code size usage than necessary, if
1274 they are disparaged too much here. So in general, if
1275 use_helper_for_const_shift thinks a helper should be used, obey
1276 that and don't disparage the shift any more than a regular
1277 instruction, even though the shift may actually cost more.
1278 This ensures that the RTL generated at the initial expand pass has the
1279 expected shift instructions, which can be mapped to the helper
1280 functions. */
1281 return msp430_costs (src, dst, speed, outer_rtx);
1284 if (!msp430x)
1286 /* Each shift by one place will be emitted individually. */
1287 switch (dst_code)
1289 case REG:
1290 case CONST_INT:
1291 return amt * cost_p->reg;
1292 case MEM:
1293 if (msp430_is_mem_indirect (dst))
1294 return amt * cost_p->ind;
1295 else
1296 return amt * cost_p->mem;
1297 default:
1298 return amt * cost_p->mem;
1302 /* RRAM, RRCM, RRUM, RLAM are used for shift counts <= 4, otherwise, the 'X'
1303 versions are used.
1304 Instructions which shift a MEM operand will never actually be output. It
1305 will always be copied into a register to allow for efficient shifting. So
1306 the cost just takes into account the cost of an additional copy in that
1307 case. */
1308 return (amt <= 4 ? (speed ? amt : 1) : (speed ? amt + 1 : 2)
1309 + (dst_code == REG ? 0
1310 : msp430_costs (dst, gen_rtx_REG (HImode, 10), speed, outer_rtx)));
1313 /* Given source operand SRC and destination operand DST from the MULT/DIV/MOD
1314 RTX OUTER_RTX, return the cost of performing that operation, assuming
1315 optimization for speed when SPEED is true. */
1316 static int
1317 msp430_muldiv_costs (rtx src, rtx dst, bool speed, rtx outer_rtx,
1318 machine_mode outer_mode)
1320 enum rtx_code outer_code = GET_CODE (outer_rtx);
1321 const struct msp430_multlib_costs *cost_p;
1322 cost_p = (msp430_use_16bit_hwmult ()
1323 ? &cycle_cost_multlib_32bit
1324 : &cycle_cost_multlib_16bit);
1326 int factor = 1;
1327 /* Only used in some calculations. */
1328 int mode_factor = 1;
1329 if (outer_mode == SImode)
1330 mode_factor = 2;
1331 else if (outer_mode == PSImode)
1332 /* PSImode multiplication is performed using SImode operands, so has extra
1333 cost to factor in the conversions necessary before/after the
1334 operation. */
1335 mode_factor = 3;
1336 else if (outer_mode == DImode)
1337 mode_factor = 4;
1339 if (!speed)
1341 /* The codesize cost of using a helper function to perform the
1342 multiplication or division cannot be accurately calculated, since the
1343 cost depends on how many times the operation is performed in the
1344 entire program. */
1345 if (outer_code != MULT)
1346 /* Division is always expensive. */
1347 factor = 7;
1348 else if (((msp430_use_16bit_hwmult () && outer_mode != DImode)
1349 || msp430_use_32bit_hwmult ()
1350 || msp430_use_f5_series_hwmult ()))
1351 /* When the hardware multiplier is available, only disparage
1352 slightly. */
1353 factor = 2;
1354 else
1355 factor = 5;
1356 return factor * mode_factor * msp430_costs (src, dst, speed, outer_rtx);
1359 /* When there is hardware multiply support, there is a relatively low, fixed
1360 cycle cost to performing any multiplication, but when there is no hardware
1361 multiply support it is very costly. That precise cycle cost has not been
1362 calculated here.
1363 Division is extra slow since it always uses a software library.
1364 The 16-bit hardware multiply library cannot be used to produce 64-bit
1365 results. */
1366 if (outer_code != MULT || !msp430_has_hwmult ()
1367 || (outer_mode == DImode && msp430_use_16bit_hwmult ()))
1369 factor = (outer_code == MULT ? 50 : 70);
1370 return factor * mode_factor * msp430_costs (src, dst, speed, outer_rtx);
1373 switch (outer_mode)
1375 case E_QImode:
1376 case E_HImode:
1377 /* Include the cost of copying the operands into and out of the hardware
1378 multiply routine. */
1379 return cost_p->mulhi + (3 * msp430_costs (src, dst, speed, outer_rtx));
1381 case E_PSImode:
1382 /* Extra factor for the conversions necessary to do PSI->SI before the
1383 operation. */
1384 factor = 2;
1385 /* fallthru. */
1386 case E_SImode:
1387 return factor * (cost_p->mulsi
1388 + (6 * msp430_costs (src, dst, speed, outer_rtx)));
1390 case E_DImode:
1391 default:
1392 return cost_p->muldi + (12 * msp430_costs (src, dst, speed, outer_rtx));
1396 /* Recurse within X to find the actual destination operand of the expression.
1397 For example:
1398 (plus (ashift (minus (ashift (reg)
1399 (const_int) ......
1400 should return the reg RTX. */
1401 static rtx
1402 msp430_get_inner_dest_code (rtx x)
1404 enum rtx_code code = GET_CODE (x);
1405 rtx op0 = XEXP (x, 0);
1406 switch (code)
1408 case REG:
1409 case SYMBOL_REF:
1410 case CONST_INT:
1411 case CONST:
1412 case LABEL_REF:
1413 return x;
1415 case MEM:
1416 /* Return the MEM expr not the inner REG for these cases. */
1417 switch (GET_CODE (op0))
1419 case REG:
1420 case SYMBOL_REF:
1421 case LABEL_REF:
1422 case CONST:
1423 case POST_INC:
1424 return x;
1426 case PLUS:
1427 /* return MEM (PLUS (REG) (CONST)) */
1428 if (GET_CODE (XEXP (op0, 0)) == REG)
1430 if (GET_CODE (XEXP (op0, 1)) == CONST_INT
1431 || GET_CODE (XEXP (op0, 1)) == CONST
1432 || GET_CODE (XEXP (op0, 1)) == LABEL_REF
1433 || GET_CODE (XEXP (op0, 1)) == SYMBOL_REF)
1434 return x;
1435 else
1436 return msp430_get_inner_dest_code (op0);
1438 return msp430_get_inner_dest_code (op0);
1440 default:
1441 if (GET_RTX_FORMAT (code)[0] != 'e')
1442 return x;
1443 return msp430_get_inner_dest_code (op0);
1445 break;
1447 default:
1448 if (op0 == NULL_RTX)
1449 gcc_unreachable ();
1450 else
1452 if (GET_RTX_FORMAT (code)[0] != 'e'
1453 && code != ENTRY_VALUE)
1454 return x;
1455 return msp430_get_inner_dest_code (op0);
1460 /* Calculate the cost of an MSP430 single-operand instruction, for operand DST
1461 within the RTX OUTER_RTX, optimizing for speed if SPEED is true. */
1462 static int
1463 msp430_single_op_cost (rtx dst, bool speed, rtx outer_rtx)
1465 enum rtx_code dst_code = GET_CODE (dst);
1466 const struct single_op_cost *cost_p;
1467 const struct double_op_cost *double_op_cost_p;
1469 cost_p = (speed ? &cycle_cost_single_op : &size_cost_single_op);
1470 double_op_cost_p = (speed ? &cycle_cost_double_op : &size_cost_double_op);
1472 switch (dst_code)
1474 case REG:
1475 return cost_p->reg;
1476 case MEM:
1477 if (msp430_is_mem_indirect (dst))
1478 return cost_p->ind;
1479 else
1480 return cost_p->mem;
1482 case CONST_INT:
1483 case CONST_FIXED:
1484 case CONST_DOUBLE:
1485 case SYMBOL_REF:
1486 case CONST:
1487 /* A constant value would need to be copied into a register first. */
1488 return double_op_cost_p->imm2r + cost_p->reg;
1490 default:
1491 return cost_p->mem;
1495 #undef TARGET_RTX_COSTS
1496 #define TARGET_RTX_COSTS msp430_rtx_costs
1498 /* This target hook describes the relative costs of RTL expressions.
1499 The function recurses to just before the lowest level of the expression,
1500 when both of the operands of the expression can be examined at the same time.
1501 This is because the cost of the expression depends on the specific
1502 addressing mode combination of the operands.
1503 The hook returns true when all subexpressions of X have been processed, and
1504 false when rtx_cost should recurse. */
1505 static bool
1506 msp430_rtx_costs (rtx x,
1507 machine_mode mode,
1508 int outer_code ATTRIBUTE_UNUSED,
1509 int opno ATTRIBUTE_UNUSED,
1510 int * total,
1511 bool speed)
1513 enum rtx_code code = GET_CODE (x);
1514 rtx dst, src;
1515 rtx dst_inner, src_inner;
1517 *total = 0;
1518 dst = XEXP (x, 0);
1519 if (GET_RTX_LENGTH (code) == 1)
1520 /* Some RTX that are single-op in GCC are double-op when translated to
1521 MSP430 instructions e.g NOT, NEG, ZERO_EXTEND. */
1522 src = dst;
1523 else
1524 src = XEXP (x, 1);
1527 switch (code)
1529 case SET:
1530 /* Ignoring SET improves codesize. */
1531 if (!speed)
1532 return true;
1533 /* fallthru. */
1534 case PLUS:
1535 if (outer_code == MEM)
1536 /* Do not add any cost for the plus itself, but recurse in case there
1537 are more complicated RTX inside. */
1538 return false;
1539 /* fallthru. */
1540 case MINUS:
1541 case AND:
1542 case IOR:
1543 case XOR:
1544 case NOT:
1545 case ZERO_EXTEND:
1546 case TRUNCATE:
1547 case NEG:
1548 case ZERO_EXTRACT:
1549 case SIGN_EXTRACT:
1550 case IF_THEN_ELSE:
1551 dst_inner = msp430_get_inner_dest_code (dst);
1552 src_inner = msp430_get_inner_dest_code (src);
1553 *total = COSTS_N_INSNS (msp430_costs (src_inner, dst_inner, speed, x));
1554 if (mode == SImode)
1555 *total *= 2;
1556 if (mode == DImode)
1557 *total *= 4;
1558 return false;
1560 case ROTATE:
1561 case ASHIFT:
1562 case ASHIFTRT:
1563 case LSHIFTRT:
1564 dst_inner = msp430_get_inner_dest_code (dst);
1565 src_inner = msp430_get_inner_dest_code (src);
1566 *total = COSTS_N_INSNS (msp430_shift_costs (src_inner, dst_inner,
1567 speed, x));
1568 if (mode == SImode)
1569 *total *= 2;
1570 if (mode == DImode)
1571 *total *= 4;
1572 return false;
1574 case MULT:
1575 case DIV:
1576 case MOD:
1577 case UDIV:
1578 case UMOD:
1579 dst_inner = msp430_get_inner_dest_code (dst);
1580 src_inner = msp430_get_inner_dest_code (src);
1581 *total = COSTS_N_INSNS (msp430_muldiv_costs (src_inner, dst_inner, speed,
1582 x, mode));
1583 return false;
1585 case CALL:
1586 case SIGN_EXTEND:
1587 dst_inner = msp430_get_inner_dest_code (dst);
1588 *total = COSTS_N_INSNS (msp430_single_op_cost (dst_inner, speed, x));
1589 if (mode == SImode)
1590 *total *= 2;
1591 if (mode == DImode)
1592 *total *= 4;
1593 return false;
1595 case CONST_INT:
1596 case CONST_FIXED:
1597 case CONST_DOUBLE:
1598 case SYMBOL_REF:
1599 case CONST:
1600 case LABEL_REF:
1601 case REG:
1602 case PC:
1603 case POST_INC:
1604 if (mode == SImode)
1605 *total = COSTS_N_INSNS (2);
1606 else if (mode == DImode)
1607 *total = COSTS_N_INSNS (4);
1608 return true;
1610 case MEM:
1611 /* PSImode operands are expensive when in memory. */
1612 if (mode == PSImode)
1613 *total = COSTS_N_INSNS (1);
1614 else if (mode == SImode)
1615 *total = COSTS_N_INSNS (2);
1616 else if (mode == DImode)
1617 *total = COSTS_N_INSNS (4);
1618 /* Recurse into the MEM. */
1619 return false;
1621 case EQ:
1622 case NE:
1623 case GT:
1624 case GTU:
1625 case GE:
1626 case GEU:
1627 case LT:
1628 case LTU:
1629 case LE:
1630 case LEU:
1631 /* Conditions are mostly equivalent, changing their relative
1632 costs has no effect. */
1633 return false;
1635 case ASM_OPERANDS:
1636 case ASM_INPUT:
1637 case CLOBBER:
1638 case COMPARE:
1639 case CONCAT:
1640 case ENTRY_VALUE:
1641 /* Other unhandled expressions. */
1642 return false;
1644 default:
1645 return false;
1649 #undef TARGET_INSN_COST
1650 #define TARGET_INSN_COST msp430_insn_cost
1652 static int
1653 msp430_insn_cost (rtx_insn *insn, bool speed ATTRIBUTE_UNUSED)
1655 if (recog_memoized (insn) < 0)
1656 return 0;
1658 /* The returned cost must be relative to COSTS_N_INSNS (1). An insn with a
1659 length of 2 bytes is the smallest possible size and so must be equivalent
1660 to COSTS_N_INSNS (1). */
1661 return COSTS_N_INSNS (get_attr_length (insn) / 2);
1663 /* FIXME Add more detailed costs when optimizing for speed.
1664 For now the length of the instruction is a good approximiation and roughly
1665 correlates with cycle cost. */
1669 /* Function Entry and Exit */
1671 /* The MSP430 call frame looks like this:
1673 <higher addresses>
1674 +--------------------+
1676 | Stack Arguments |
1678 +--------------------+ <-- "arg pointer"
1680 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1682 +--------------------+
1683 | SR if this func has|
1684 | been called via an |
1685 | interrupt. |
1686 +--------------------+ <-- SP before prologue, also AP
1688 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1690 +--------------------+ <-- "frame pointer"
1692 | Locals |
1694 +--------------------+
1696 | Outgoing Args |
1698 +--------------------+ <-- SP during function
1699 <lower addresses>
1703 /* We use this to wrap all emitted insns in the prologue, so they get
1704 the "frame-related" (/f) flag set. */
1705 static rtx
1706 F (rtx x)
1708 RTX_FRAME_RELATED_P (x) = 1;
1709 return x;
1712 /* This is the one spot that decides if a register is to be saved and
1713 restored in the prologue/epilogue. */
1714 static bool
1715 msp430_preserve_reg_p (int regno)
1717 /* PC, SP, SR, and the constant generator. */
1718 if (regno <= 3)
1719 return false;
1721 /* FIXME: add interrupt, EH, etc. */
1722 if (crtl->calls_eh_return)
1723 return true;
1725 /* Shouldn't be more than the above, but just in case... */
1726 if (fixed_regs[regno])
1727 return false;
1729 /* For interrupt functions we must save and restore the used regs that
1730 would normally be caller-saved (R11->R15). */
1731 if (msp430_is_interrupt_func () && regno >= 11 && regno <= 15)
1733 if (crtl->is_leaf && df_regs_ever_live_p (regno))
1734 /* If the interrupt func is a leaf then we only need to restore the
1735 caller-saved regs that are used. */
1736 return true;
1737 else if (!crtl->is_leaf)
1738 /* If the interrupt function is not a leaf we must save all
1739 caller-saved regs in case the callee modifies them. */
1740 return true;
1743 if (!call_used_or_fixed_reg_p (regno)
1744 && df_regs_ever_live_p (regno))
1745 return true;
1747 return false;
1750 /* Compute all the frame-related fields in our machine_function
1751 structure. */
1752 static void
1753 msp430_compute_frame_info (void)
1755 int i;
1757 cfun->machine->computed = 1;
1758 cfun->machine->framesize_regs = 0;
1759 cfun->machine->framesize_locals = get_frame_size ();
1760 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
1762 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1763 if (msp430_preserve_reg_p (i))
1765 cfun->machine->need_to_save[i] = 1;
1766 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1768 else
1769 cfun->machine->need_to_save[i] = 0;
1771 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1772 cfun->machine->framesize_locals ++;
1774 cfun->machine->framesize = (cfun->machine->framesize_regs
1775 + cfun->machine->framesize_locals
1776 + cfun->machine->framesize_outgoing);
1779 /* Attribute Handling. */
1781 const char * const ATTR_INTR = "interrupt";
1782 const char * const ATTR_WAKEUP = "wakeup";
1783 const char * const ATTR_NAKED = "naked";
1784 const char * const ATTR_REENT = "reentrant";
1785 const char * const ATTR_CRIT = "critical";
1786 const char * const ATTR_LOWER = "lower";
1787 const char * const ATTR_UPPER = "upper";
1788 const char * const ATTR_EITHER = "either";
1789 const char * const ATTR_NOINIT = "noinit";
1790 const char * const ATTR_PERSIST = "persistent";
1792 static inline bool
1793 has_attr (const char * attr, tree decl)
1795 if (decl == NULL_TREE)
1796 return false;
1797 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1800 static bool
1801 is_interrupt_func (tree decl = current_function_decl)
1803 return has_attr (ATTR_INTR, decl);
1806 /* Returns true if the current function has the "interrupt" attribute. */
1808 bool
1809 msp430_is_interrupt_func (void)
1811 return is_interrupt_func (current_function_decl);
1814 static bool
1815 is_wakeup_func (tree decl = current_function_decl)
1817 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1820 static inline bool
1821 is_naked_func (tree decl = current_function_decl)
1823 return has_attr (ATTR_NAKED, decl);
1826 static inline bool
1827 is_reentrant_func (tree decl = current_function_decl)
1829 return has_attr (ATTR_REENT, decl);
1832 static inline bool
1833 is_critical_func (tree decl = current_function_decl)
1835 return has_attr (ATTR_CRIT, decl);
1838 static bool
1839 has_section_name (const char * name, tree decl = current_function_decl)
1841 if (decl == NULL_TREE)
1842 return false;
1843 return (DECL_SECTION_NAME (decl)
1844 && (strcmp (name, DECL_SECTION_NAME (decl)) == 0));
1847 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1848 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
1849 msp430_allocate_stack_slots_for_args
1851 static bool
1852 msp430_allocate_stack_slots_for_args (void)
1854 /* Naked functions should not allocate stack slots for arguments. */
1855 return ! is_naked_func ();
1858 #undef TARGET_WARN_FUNC_RETURN
1859 #define TARGET_WARN_FUNC_RETURN msp430_warn_func_return
1861 static bool
1862 msp430_warn_func_return (tree decl)
1864 /* Naked functions are implemented entirely in assembly, including the
1865 return sequence, so suppress warnings about this. */
1866 return !is_naked_func (decl);
1869 /* Verify MSP430 specific attributes. */
1870 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1872 static tree
1873 msp430_attr (tree * node,
1874 tree name,
1875 tree args,
1876 int flags ATTRIBUTE_UNUSED,
1877 bool * no_add_attrs)
1879 gcc_assert (DECL_P (* node));
1881 /* Only the interrupt attribute takes an argument. */
1882 if (args != NULL)
1884 tree value = TREE_VALUE (args);
1886 switch (TREE_CODE (value))
1888 case STRING_CST:
1889 if ( strcmp (TREE_STRING_POINTER (value), "reset")
1890 && strcmp (TREE_STRING_POINTER (value), "nmi")
1891 && strcmp (TREE_STRING_POINTER (value), "watchdog"))
1892 /* Allow the attribute to be added - the linker script
1893 being used may still recognise this name. */
1894 warning (OPT_Wattributes,
1895 "unrecognized interrupt vector argument of %qE attribute",
1896 name);
1897 break;
1899 case INTEGER_CST:
1900 if (wi::gtu_p (wi::to_wide (value), 63))
1901 /* Allow the attribute to be added - the linker script
1902 being used may still recognise this value. */
1903 warning (OPT_Wattributes,
1904 "numeric argument of %qE attribute must be in range 0..63",
1905 name);
1906 break;
1908 default:
1909 warning (OPT_Wattributes,
1910 "argument of %qE attribute is not a string constant "
1911 "or number", name);
1912 *no_add_attrs = true;
1913 break;
1917 const char * message = NULL;
1919 if (TREE_CODE (* node) != FUNCTION_DECL)
1921 message = "%qE attribute only applies to functions";
1923 else if (TREE_NAME_EQ (name, ATTR_INTR))
1925 if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE
1926 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node))))
1927 message = "interrupt handlers must be void";
1928 else
1930 /* Ensure interrupt handlers never get optimised out. */
1931 TREE_USED (* node) = 1;
1932 DECL_PRESERVE_P (* node) = 1;
1934 if (is_critical_func (* node))
1936 /* We always ignore the critical attribute when interrupt and
1937 critical are used together. */
1938 warning (OPT_Wattributes,
1939 "critical attribute has no effect on interrupt functions");
1940 DECL_ATTRIBUTES (*node) = remove_attribute (ATTR_CRIT,
1941 DECL_ATTRIBUTES (* node));
1944 else if (TREE_NAME_EQ (name, ATTR_CRIT))
1946 if (is_interrupt_func ( *node))
1947 message = "critical attribute has no effect on interrupt functions";
1950 if (message)
1952 warning (OPT_Wattributes, message, name);
1953 * no_add_attrs = true;
1956 return NULL_TREE;
1959 static tree
1960 msp430_section_attr (tree * node,
1961 tree name,
1962 tree args,
1963 int flags ATTRIBUTE_UNUSED,
1964 bool * no_add_attrs ATTRIBUTE_UNUSED)
1966 gcc_assert (DECL_P (* node));
1967 gcc_assert (args == NULL);
1969 const char * message = NULL;
1971 /* The "noinit", "persistent", and "section" attributes are handled
1972 generically, so we cannot set up additional target-specific attribute
1973 exclusions using the existing mechanism. */
1974 if (has_attr (ATTR_NOINIT, *node) && !TREE_NAME_EQ (name, "lower"))
1975 message = G_("ignoring attribute %qE because it conflicts with "
1976 "attribute %<noinit%>");
1977 else if (has_attr ("section", *node) && !TREE_NAME_EQ (name, "lower"))
1978 message = G_("ignoring attribute %qE because it conflicts with "
1979 "attribute %<section%>");
1980 else if (has_attr (ATTR_PERSIST, *node) && !TREE_NAME_EQ (name, "lower"))
1981 message = G_("ignoring attribute %qE because it conflicts with "
1982 "attribute %<persistent%>");
1983 /* It does not make sense to use upper/lower/either attributes without
1984 -mlarge.
1985 Without -mlarge, "lower" is the default and only region, so is redundant.
1986 Without -mlarge, "upper" will (and "either" might) place code/data in the
1987 upper region, which for data could result in relocation overflows, and for
1988 code could result in stack mismanagement and incorrect call/return
1989 instructions. */
1990 else if (!TARGET_LARGE)
1991 message = G_("%qE attribute ignored. Large memory model (%<-mlarge%>) "
1992 "is required.");
1994 if (message)
1996 warning (OPT_Wattributes, message, name);
1997 * no_add_attrs = true;
2000 return NULL_TREE;
2003 /* Helper to define attribute exclusions. */
2004 #define ATTR_EXCL(name, function, type, variable) \
2005 { name, function, type, variable }
2007 /* "reentrant", "critical" and "naked" functions must conflict because
2008 they all modify the prologue or epilogue of functions in mutually exclusive
2009 ways. */
2010 static const struct attribute_spec::exclusions attr_reent_exclusions[] =
2012 ATTR_EXCL (ATTR_NAKED, true, true, true),
2013 ATTR_EXCL (ATTR_CRIT, true, true, true),
2014 ATTR_EXCL (NULL, false, false, false)
2017 static const struct attribute_spec::exclusions attr_naked_exclusions[] =
2019 ATTR_EXCL (ATTR_REENT, true, true, true),
2020 ATTR_EXCL (ATTR_CRIT, true, true, true),
2021 ATTR_EXCL (NULL, false, false, false)
2024 static const struct attribute_spec::exclusions attr_crit_exclusions[] =
2026 ATTR_EXCL (ATTR_REENT, true, true, true),
2027 ATTR_EXCL (ATTR_NAKED, true, true, true),
2028 ATTR_EXCL (NULL, false, false, false)
2031 /* Attributes which put the given object in a specific section must conflict
2032 with one another. */
2033 static const struct attribute_spec::exclusions attr_lower_exclusions[] =
2035 ATTR_EXCL (ATTR_UPPER, true, true, true),
2036 ATTR_EXCL (ATTR_EITHER, true, true, true),
2037 ATTR_EXCL (NULL, false, false, false)
2040 static const struct attribute_spec::exclusions attr_upper_exclusions[] =
2042 ATTR_EXCL (ATTR_LOWER, true, true, true),
2043 ATTR_EXCL (ATTR_EITHER, true, true, true),
2044 ATTR_EXCL (NULL, false, false, false)
2047 static const struct attribute_spec::exclusions attr_either_exclusions[] =
2049 ATTR_EXCL (ATTR_LOWER, true, true, true),
2050 ATTR_EXCL (ATTR_UPPER, true, true, true),
2051 ATTR_EXCL (NULL, false, false, false)
2054 #undef TARGET_ATTRIBUTE_TABLE
2055 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
2057 /* Table of MSP430-specific attributes. */
2058 const struct attribute_spec msp430_attribute_table[] =
2060 /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
2061 affects_type_identity, handler, exclude } */
2062 { ATTR_INTR, 0, 1, true, false, false, false, msp430_attr, NULL },
2063 { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr,
2064 attr_naked_exclusions },
2065 { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr,
2066 attr_reent_exclusions },
2067 { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr,
2068 attr_crit_exclusions },
2069 { ATTR_WAKEUP, 0, 0, true, false, false, false, msp430_attr, NULL },
2071 { ATTR_LOWER, 0, 0, true, false, false, false, msp430_section_attr,
2072 attr_lower_exclusions },
2073 { ATTR_UPPER, 0, 0, true, false, false, false, msp430_section_attr,
2074 attr_upper_exclusions },
2075 { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr,
2076 attr_either_exclusions },
2078 { NULL, 0, 0, false, false, false, false, NULL, NULL }
2081 #undef TARGET_HANDLE_GENERIC_ATTRIBUTE
2082 #define TARGET_HANDLE_GENERIC_ATTRIBUTE msp430_handle_generic_attribute
2084 tree
2085 msp430_handle_generic_attribute (tree *node,
2086 tree name,
2087 tree args ATTRIBUTE_UNUSED,
2088 int flags ATTRIBUTE_UNUSED,
2089 bool *no_add_attrs)
2092 const char *message = NULL;
2094 /* Permit the "lower" attribute to be set on variables with the "section",
2095 "noinit" and "persistent" attributes. This is used to indicate that the
2096 corresponding output section will be in lower memory, so a 430X
2097 instruction is not required to handle it. */
2098 if (has_attr (ATTR_LOWER, *node)
2099 && !(TREE_NAME_EQ (name, "section") || TREE_NAME_EQ (name, ATTR_PERSIST)
2100 || TREE_NAME_EQ (name, ATTR_NOINIT)))
2101 message = G_("ignoring attribute %qE because it conflicts with "
2102 "attribute %<lower%>");
2103 else if (has_attr (ATTR_UPPER, *node))
2104 message = G_("ignoring attribute %qE because it conflicts with "
2105 "attribute %<upper%>");
2106 else if (has_attr (ATTR_EITHER, *node))
2107 message = G_("ignoring attribute %qE because it conflicts with "
2108 "attribute %<either%>");
2110 if (message)
2112 warning (OPT_Wattributes, message, name);
2113 *no_add_attrs = true;
2116 return NULL_TREE;
2119 /* Given a non-automatic VAR_DECL which can possibly have a section, return
2120 true if the variable will definitely be placed in the lower memory
2121 region (below address 0x10000). */
2122 static bool
2123 msp430_var_in_low_mem (tree decl)
2125 gcc_assert (VAR_P (decl));
2127 /* "noinit" variables are always placed in the lower memory region. */
2128 if (has_attr (ATTR_UPPER, decl)
2129 || has_attr (ATTR_EITHER, decl)
2130 || has_attr (ATTR_PERSIST, decl)
2131 /* Unless the variable is marked with the lower or noinit attribute, we
2132 cannot assume that it is in the lower region if it is marked with the
2133 section attribute or -mdata-region={upper,either,none} have been
2134 passed.
2135 The noinit and section attributes conflict. */
2136 || (!has_attr (ATTR_LOWER, decl) && !has_attr (ATTR_NOINIT, decl)
2137 && (has_attr ("section", decl)
2138 || msp430_data_region == MSP430_REGION_UPPER
2139 || msp430_data_region == MSP430_REGION_EITHER
2140 || msp430_data_region == MSP430_REGION_ANY)))
2141 return false;
2142 return true;
2145 #undef TARGET_ENCODE_SECTION_INFO
2146 #define TARGET_ENCODE_SECTION_INFO msp430_encode_section_info
2148 /* Encode whether a SYMBOL_REF is definitely in the lower memory region. */
2149 static void
2150 msp430_encode_section_info (tree decl, rtx rtl, int first)
2152 rtx symbol;
2153 default_encode_section_info (decl, rtl, first);
2155 /* Careful not to prod global register variables. */
2156 if (!MEM_P (rtl))
2157 return;
2158 symbol = XEXP (rtl, 0);
2159 if (GET_CODE (symbol) != SYMBOL_REF)
2160 return;
2162 if (VAR_P (decl)
2163 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
2164 && msp430_var_in_low_mem (decl))
2165 SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOW_MEM;
2168 #undef TARGET_ASM_FUNCTION_PROLOGUE
2169 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
2171 static void
2172 msp430_start_function (FILE *outfile)
2174 int r, n;
2176 fprintf (outfile, "; start of function\n");
2178 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
2180 fprintf (outfile, "; attributes: ");
2181 if (is_naked_func ())
2182 fprintf (outfile, "naked ");
2183 if (msp430_is_interrupt_func ())
2184 fprintf (outfile, "interrupt ");
2185 if (is_reentrant_func ())
2186 fprintf (outfile, "reentrant ");
2187 if (is_critical_func ())
2188 fprintf (outfile, "critical ");
2189 if (is_wakeup_func ())
2190 fprintf (outfile, "wakeup ");
2191 fprintf (outfile, "\n");
2194 fprintf (outfile, "; framesize_regs: %d\n",
2195 cfun->machine->framesize_regs);
2196 fprintf (outfile, "; framesize_locals: %d\n",
2197 cfun->machine->framesize_locals);
2198 fprintf (outfile, "; framesize_outgoing: %d\n",
2199 cfun->machine->framesize_outgoing);
2200 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
2201 fprintf (outfile, "; elim ap -> fp %d\n",
2202 msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
2203 FRAME_POINTER_REGNUM));
2204 fprintf (outfile, "; elim fp -> sp %d\n",
2205 msp430_initial_elimination_offset (FRAME_POINTER_REGNUM,
2206 STACK_POINTER_REGNUM));
2208 n = 0;
2209 fprintf (outfile, "; saved regs:");
2210 for (r = 0; r < ARG_POINTER_REGNUM; r++)
2211 if (cfun->machine->need_to_save[r])
2213 fprintf (outfile, " %s", reg_names[r]);
2214 n = 1;
2216 if (n == 0)
2217 fprintf (outfile, "(none)");
2218 fprintf (outfile, "\n");
2221 /* Common code to change the stack pointer. */
2222 static void
2223 increment_stack (HOST_WIDE_INT amount)
2225 rtx inc;
2226 rtx sp = stack_pointer_rtx;
2228 if (amount == 0)
2229 return;
2231 if (amount < 0)
2233 inc = GEN_INT (- amount);
2234 if (TARGET_LARGE)
2235 F (emit_insn (gen_subpsi3 (sp, sp, inc)));
2236 else
2237 F (emit_insn (gen_subhi3 (sp, sp, inc)));
2239 else
2241 inc = GEN_INT (amount);
2242 if (TARGET_LARGE)
2243 F (emit_insn (gen_addpsi3 (sp, sp, inc)));
2244 else
2245 F (emit_insn (gen_addhi3 (sp, sp, inc)));
2249 void
2250 msp430_start_function (FILE *file, const char *name, tree decl)
2252 tree int_attr;
2254 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2255 if (int_attr != NULL_TREE)
2257 tree intr_vector = TREE_VALUE (int_attr);
2259 if (intr_vector != NULL_TREE)
2261 char buf[101];
2263 /* Interrupt vector sections should be unique, but use of weak
2264 functions implies multiple definitions. */
2265 if (DECL_WEAK (decl))
2267 error ("argument to interrupt attribute is unsupported for weak "
2268 "functions");
2271 intr_vector = TREE_VALUE (intr_vector);
2273 /* The interrupt attribute has a vector value. Turn this into a
2274 section name, switch to that section and put the address of
2275 the current function into that vector slot. Note msp430_attr()
2276 has already verified the vector name for us. */
2277 if (TREE_CODE (intr_vector) == STRING_CST)
2278 sprintf (buf, "__interrupt_vector_%.80s",
2279 TREE_STRING_POINTER (intr_vector));
2280 else /* TREE_CODE (intr_vector) == INTEGER_CST */
2281 sprintf (buf, "__interrupt_vector_%u",
2282 (unsigned int) TREE_INT_CST_LOW (intr_vector));
2284 switch_to_section (get_section (buf, SECTION_CODE, decl));
2285 fputs ("\t.word\t", file);
2286 assemble_name (file, name);
2287 fputc ('\n', file);
2288 fputc ('\t', file);
2292 switch_to_section (function_section (decl));
2293 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
2294 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
2297 static const char * const lower_prefix = ".lower";
2298 static const char * const upper_prefix = ".upper";
2299 static const char * const either_prefix = ".either";
2301 /* Generate a prefix for a section name, based upon
2302 the region into which the object should be placed. */
2304 static const char *
2305 gen_prefix (tree decl)
2307 if (DECL_ONE_ONLY (decl))
2308 return NULL;
2310 /* If the user has specified a particular section then do not use any
2311 prefix. */
2312 if (has_attr ("section", decl))
2313 return NULL;
2315 /* If the function has been put in the .lowtext section (because it is an
2316 interrupt handler, and the large memory model is used), then do not add
2317 any prefixes. */
2318 if (has_section_name (".lowtext", decl))
2319 return NULL;
2321 /* Memory regions require the large memory model. */
2322 if (!TARGET_LARGE)
2323 return NULL;
2325 /* Note that we always apply the lower prefix when the attribute has been
2326 used. But we only apply the lower prefix when the lower region has been
2327 specified by a command line option if -muse-lower-region-prefix has also
2328 been passed. */
2329 if (has_attr (ATTR_LOWER, decl))
2330 return lower_prefix;
2332 if (has_attr (ATTR_UPPER, decl))
2333 return upper_prefix;
2335 if (has_attr (ATTR_EITHER, decl))
2336 return either_prefix;
2338 if (TREE_CODE (decl) == FUNCTION_DECL)
2340 if ((msp430_code_region == MSP430_REGION_LOWER)
2341 && TARGET_USE_LOWER_REGION_PREFIX)
2342 return lower_prefix;
2344 if (msp430_code_region == MSP430_REGION_UPPER)
2345 return upper_prefix;
2347 if (msp430_code_region == MSP430_REGION_EITHER)
2348 return either_prefix;
2350 else
2352 if ((msp430_data_region == MSP430_REGION_LOWER)
2353 && TARGET_USE_LOWER_REGION_PREFIX)
2354 return lower_prefix;
2356 if (msp430_data_region == MSP430_REGION_UPPER)
2357 return upper_prefix;
2359 if (msp430_data_region == MSP430_REGION_EITHER)
2360 return either_prefix;
2363 return NULL;
2366 #undef TARGET_ASM_SELECT_SECTION
2367 #define TARGET_ASM_SELECT_SECTION msp430_select_section
2369 static section *
2370 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
2372 const char *prefix;
2373 const char *sec_name;
2374 const char *base_sec_name;
2376 gcc_assert (decl != NULL_TREE);
2378 if (TREE_CODE (decl) == STRING_CST
2379 || TREE_CODE (decl) == CONSTRUCTOR
2380 || TREE_CODE (decl) == INTEGER_CST
2381 || TREE_CODE (decl) == VECTOR_CST
2382 || TREE_CODE (decl) == COMPLEX_CST)
2383 return default_select_section (decl, reloc, align);
2385 /* In large mode we must make sure that interrupt handlers are put into
2386 low memory as the vector table only accepts 16-bit addresses. */
2387 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
2388 && is_interrupt_func (decl))
2389 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
2391 /* The "noinit" and "persistent" attributes are handled generically. */
2392 if (has_attr (ATTR_NOINIT, decl) || has_attr (ATTR_PERSIST, decl))
2393 return default_elf_select_section (decl, reloc, align);
2395 prefix = gen_prefix (decl);
2397 switch (categorize_decl_for_section (decl, reloc))
2399 case SECCAT_TEXT:
2400 if (!prefix)
2401 return text_section;
2402 base_sec_name = ".text";
2403 break;
2404 case SECCAT_DATA:
2405 if (!prefix)
2406 return data_section;
2407 base_sec_name = ".data";
2408 break;
2409 case SECCAT_BSS:
2410 if (!prefix)
2411 return bss_section;
2412 base_sec_name = ".bss";
2413 break;
2414 case SECCAT_RODATA:
2415 if (!prefix)
2416 return readonly_data_section;
2417 base_sec_name = ".rodata";
2418 break;
2420 /* Enable merging of constant data by the GNU linker using
2421 default_elf_select_section and therefore enabling creation of
2422 sections with the SHF_MERGE flag. */
2423 case SECCAT_RODATA_MERGE_STR:
2424 case SECCAT_RODATA_MERGE_STR_INIT:
2425 case SECCAT_RODATA_MERGE_CONST:
2426 return default_elf_select_section (decl, reloc, align);
2428 /* The sections listed below are not supported for MSP430.
2429 They should not be generated, but in case they are, we use
2430 default_select_section so they get placed in sections
2431 the msp430 assembler and linker understand. */
2432 /* "small data" sections are not supported. */
2433 case SECCAT_SRODATA:
2434 case SECCAT_SDATA:
2435 case SECCAT_SBSS:
2436 /* Thread-local storage (TLS) is not supported. */
2437 case SECCAT_TDATA:
2438 case SECCAT_TBSS:
2439 /* Sections used by a dynamic linker are not supported. */
2440 case SECCAT_DATA_REL:
2441 case SECCAT_DATA_REL_LOCAL:
2442 case SECCAT_DATA_REL_RO:
2443 case SECCAT_DATA_REL_RO_LOCAL:
2444 return default_select_section (decl, reloc, align);
2446 default:
2447 gcc_unreachable ();
2450 sec_name = ACONCAT ((prefix, base_sec_name, DECL_SECTION_NAME (decl), NULL));
2452 return get_named_section (decl, sec_name, 0);
2455 #undef TARGET_ASM_FUNCTION_SECTION
2456 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
2458 static section *
2459 msp430_function_section (tree decl, enum node_frequency freq, bool startup,
2460 bool exit)
2462 const char * name;
2464 gcc_assert (DECL_SECTION_NAME (decl) != NULL);
2465 name = DECL_SECTION_NAME (decl);
2467 const char * prefix = gen_prefix (decl);
2468 if (prefix == NULL
2469 || strncmp (name, prefix, strlen (prefix)) == 0)
2470 return default_function_section (decl, freq, startup, exit);
2472 name = ACONCAT ((prefix, name, NULL));
2473 return get_named_section (decl, name, 0);
2476 #undef TARGET_SECTION_TYPE_FLAGS
2477 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
2479 unsigned int
2480 msp430_section_type_flags (tree decl, const char * name, int reloc)
2482 if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0)
2483 name += strlen (lower_prefix);
2484 else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0)
2485 name += strlen (upper_prefix);
2486 else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
2487 name += strlen (either_prefix);
2489 return default_section_type_flags (decl, name, reloc);
2492 #undef TARGET_ASM_UNIQUE_SECTION
2493 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
2495 static void
2496 msp430_unique_section (tree decl, int reloc)
2498 gcc_assert (decl != NULL_TREE);
2500 /* In large mode we must make sure that interrupt handlers are put into
2501 low memory as the vector table only accepts 16-bit addresses. */
2502 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
2503 && is_interrupt_func (decl))
2505 set_decl_section_name (decl, ".lowtext");
2506 return;
2509 default_unique_section (decl, reloc);
2511 const char * prefix;
2513 if ( TREE_CODE (decl) == STRING_CST
2514 || TREE_CODE (decl) == CONSTRUCTOR
2515 || TREE_CODE (decl) == INTEGER_CST
2516 || TREE_CODE (decl) == VECTOR_CST
2517 || TREE_CODE (decl) == COMPLEX_CST
2518 || (prefix = gen_prefix (decl)) == NULL)
2519 return;
2521 const char * dec_name = DECL_SECTION_NAME (decl);
2522 char * name = ACONCAT ((prefix, dec_name, NULL));
2524 set_decl_section_name (decl, name);
2527 /* Emit a declaration of a common symbol.
2528 If a data region is in use then put the symbol into the
2529 equivalent .bss section instead.
2530 If LOCAL is 1, then DECL is for a local common variable. */
2531 void
2532 msp430_output_aligned_decl_common (FILE * stream,
2533 const tree decl,
2534 const char * name,
2535 unsigned HOST_WIDE_INT size,
2536 unsigned int align,
2537 int local)
2539 /* Only emit a common symbol if the variable does not have a specific section
2540 assigned. */
2541 if ((msp430_data_region == MSP430_REGION_ANY
2542 || ((msp430_data_region == MSP430_REGION_LOWER)
2543 && !TARGET_USE_LOWER_REGION_PREFIX))
2544 && !(decl != NULL_TREE && DECL_SECTION_NAME (decl))
2545 && !has_attr (ATTR_EITHER, decl)
2546 && !has_attr (ATTR_LOWER, decl)
2547 && !has_attr (ATTR_UPPER, decl)
2548 && !has_attr (ATTR_PERSIST, decl)
2549 && !has_attr (ATTR_NOINIT, decl))
2551 if (local)
2553 fprintf (stream, LOCAL_ASM_OP);
2554 assemble_name (stream, name);
2555 fprintf (stream, "\n");
2557 fprintf (stream, COMMON_ASM_OP);
2558 assemble_name (stream, name);
2559 fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
2560 size, align / BITS_PER_UNIT);
2562 else
2564 section * sec;
2566 if (decl)
2567 sec = msp430_select_section (decl, 0, align);
2568 else
2569 switch (msp430_data_region)
2571 case MSP430_REGION_UPPER:
2572 sec = get_named_section (NULL, ".upper.bss", 0);
2573 break;
2574 case MSP430_REGION_LOWER:
2575 sec = get_named_section (NULL, ".lower.bss", 0);
2576 break;
2577 case MSP430_REGION_EITHER:
2578 sec = get_named_section (NULL, ".either.bss", 0);
2579 break;
2580 default:
2581 gcc_unreachable ();
2583 gcc_assert (sec != NULL);
2585 switch_to_section (sec);
2586 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
2587 if (!local)
2589 targetm.asm_out.globalize_label (stream, name);
2590 ASM_WEAKEN_LABEL (stream, name);
2592 ASM_OUTPUT_LABEL (stream, name);
2593 ASM_OUTPUT_SKIP (stream, size ? size : 1);
2597 #undef TARGET_ASM_FILE_END
2598 #define TARGET_ASM_FILE_END msp430_file_end
2600 /* Emit MSPABI and GNU object attributes.
2601 Tags and values for MSPABI attributes are:
2602 OFBA_MSPABI_Tag_ISA 4
2603 MSP430 1
2604 MSP430X 2
2605 OFBA_MSPABI_Tag_Code_Model 6
2606 Small 1
2607 Large 2
2608 OFBA_MSPABI_Tag_Data_Model 8
2609 Small 1
2610 Large 2
2611 Restricted 3 (Unused by GNU)
2612 OFBA_MSPABI_Tag_enum_size 10 (Unused by GNU)
2613 Note that Code_Model and Data_Model are always equal for GNU.
2614 We define a new .gnu_attribute to keep track of the data region used.
2615 Tag_GNU_MSP430_Data_Region 4
2616 LOWER 1
2617 ANY 2
2618 See binutils-gdb/include/elf/msp430.h for the full details. */
2619 static void
2620 msp430_file_end (void)
2622 #ifdef HAVE_AS_MSPABI_ATTRIBUTE
2623 /* Enum for tag names. */
2624 enum
2626 OFBA_MSPABI_Tag_ISA = 4,
2627 OFBA_MSPABI_Tag_Code_Model = 6,
2628 OFBA_MSPABI_Tag_Data_Model = 8,
2629 Tag_GNU_MSP430_Data_Region = 4
2631 /* Enum for tag values. */
2632 enum
2634 OFBA_MSPABI_Val_ISA_MSP430 = 1,
2635 OFBA_MSPABI_Val_ISA_MSP430X = 2,
2636 OFBA_MSPABI_Val_Model_Small = 1,
2637 OFBA_MSPABI_Val_Model_Large = 2,
2638 Tag_GNU_MSP430_Data_Region_Lower = 1,
2639 Tag_GNU_MSP430_Data_Region_Any = 2
2641 /* .mspabi_attribute is a GNU assembler directive only. The assembler will
2642 construct a .MSP430.attributes section based on the options it is invoked
2643 with. The values it reads from these directives are used for validating
2644 those options. */
2645 const char *msp430_attr = ".mspabi_attribute";
2646 const char *gnu_attr = ".gnu_attribute";
2648 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_ISA. */
2649 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr, OFBA_MSPABI_Tag_ISA,
2650 msp430x ? OFBA_MSPABI_Val_ISA_MSP430X : OFBA_MSPABI_Val_ISA_MSP430);
2651 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Code_Model. */
2652 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2653 OFBA_MSPABI_Tag_Code_Model,
2654 TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2655 : OFBA_MSPABI_Val_Model_Small);
2656 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Data_Model. */
2657 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2658 OFBA_MSPABI_Tag_Data_Model,
2659 TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2660 : OFBA_MSPABI_Val_Model_Small);
2661 #ifdef HAVE_AS_GNU_ATTRIBUTE
2662 /* Emit .gnu_attribute directive for Tag_GNU_MSP430_Data_Region. */
2663 fprintf (asm_out_file, "\t%s %d, %d\n", gnu_attr, Tag_GNU_MSP430_Data_Region,
2664 msp430_data_region == MSP430_REGION_LOWER
2665 ? Tag_GNU_MSP430_Data_Region_Lower
2666 : Tag_GNU_MSP430_Data_Region_Any);
2667 #endif
2668 #endif
2671 enum msp430_builtin
2673 MSP430_BUILTIN_BIC_SR,
2674 MSP430_BUILTIN_BIS_SR,
2675 MSP430_BUILTIN_DELAY_CYCLES,
2676 MSP430_BUILTIN_max
2679 static GTY(()) tree msp430_builtins[(int) MSP430_BUILTIN_max];
2681 static void
2682 msp430_init_builtins (void)
2684 tree void_ftype_int = build_function_type_list (void_type_node,
2685 integer_type_node, NULL);
2686 tree void_ftype_longlong
2687 = build_function_type_list (void_type_node, long_long_integer_type_node,
2688 NULL);
2690 msp430_builtins[MSP430_BUILTIN_BIC_SR] =
2691 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
2692 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
2694 msp430_builtins[MSP430_BUILTIN_BIS_SR] =
2695 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
2696 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
2698 msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
2699 add_builtin_function ( "__delay_cycles", void_ftype_longlong,
2700 MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL,
2701 NULL_TREE);
2704 static tree
2705 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
2707 switch (code)
2709 case MSP430_BUILTIN_BIC_SR:
2710 case MSP430_BUILTIN_BIS_SR:
2711 case MSP430_BUILTIN_DELAY_CYCLES:
2712 return msp430_builtins[code];
2713 default:
2714 return error_mark_node;
2718 /* These constants are really register reads, which are faster than
2719 regular constants. */
2720 static int
2721 cg_magic_constant (HOST_WIDE_INT c)
2723 switch (c)
2725 case 0xffff:
2726 case -1:
2727 case 0:
2728 case 1:
2729 case 2:
2730 case 4:
2731 case 8:
2732 return 1;
2733 default:
2734 return 0;
2738 static rtx
2739 msp430_expand_delay_cycles (rtx arg)
2741 HOST_WIDE_INT i, c, n;
2742 /* extra cycles for MSP430X instructions */
2743 #define CYCX(M,X) (msp430x ? (X) : (M))
2745 if (GET_CODE (arg) != CONST_INT)
2747 error ("__delay_cycles() only takes constant arguments");
2748 return NULL_RTX;
2751 c = INTVAL (arg);
2753 if (HOST_BITS_PER_WIDE_INT > 32)
2755 if (c < 0)
2757 error ("__delay_cycles only takes non-negative cycle counts");
2758 return NULL_RTX;
2762 emit_insn (gen_delay_cycles_start (arg));
2764 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
2765 if (c > 3 * 0xffff + CYCX (7, 10))
2767 n = c;
2768 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long
2769 (x<=0xffff) loop. */
2770 if (c >= 0x10000 * 7 + CYCX (14, 16))
2772 i = 0x10000;
2773 c -= CYCX (14, 16) + 7 * 0x10000;
2774 i += c / 4;
2775 c %= 4;
2776 if ((unsigned long long) i > 0xffffffffULL)
2778 error ("__delay_cycles is limited to 32-bit loop counts");
2779 return NULL_RTX;
2782 else
2784 i = (c - CYCX (14, 16)) / 7;
2785 c -= CYCX (14, 16) + i * 7;
2788 if (cg_magic_constant (i & 0xffff))
2789 c ++;
2790 if (cg_magic_constant ((i >> 16) & 0xffff))
2791 c ++;
2793 if (msp430x)
2794 emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c)));
2795 else
2796 emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
2799 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is
2800 0x30004(7). */
2801 if (c > 12)
2803 n = c;
2804 i = (c - CYCX (7, 10)) / 3;
2805 c -= CYCX (7, 10) + i * 3;
2807 if (cg_magic_constant (i))
2808 c ++;
2810 if (msp430x)
2811 emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c)));
2812 else
2813 emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c)));
2816 while (c > 1)
2818 emit_insn (gen_delay_cycles_2 ());
2819 c -= 2;
2822 if (c)
2824 emit_insn (gen_delay_cycles_1 ());
2825 c -= 1;
2828 emit_insn (gen_delay_cycles_end (arg));
2830 return NULL_RTX;
2833 static rtx
2834 msp430_expand_builtin (tree exp,
2835 rtx target ATTRIBUTE_UNUSED,
2836 rtx subtarget ATTRIBUTE_UNUSED,
2837 machine_mode mode ATTRIBUTE_UNUSED,
2838 int ignore ATTRIBUTE_UNUSED)
2840 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2841 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
2842 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2844 if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
2845 return msp430_expand_delay_cycles (arg1);
2847 if (! msp430_is_interrupt_func ())
2849 error ("MSP430 builtin functions only work inside interrupt handlers");
2850 return NULL_RTX;
2853 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
2854 arg1 = force_reg (mode, arg1);
2856 switch (fcode)
2858 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break;
2859 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break;
2860 default:
2861 internal_error ("bad builtin code");
2862 break;
2864 return NULL_RTX;
2867 #undef TARGET_INIT_BUILTINS
2868 #define TARGET_INIT_BUILTINS msp430_init_builtins
2870 #undef TARGET_EXPAND_BUILTIN
2871 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
2873 #undef TARGET_BUILTIN_DECL
2874 #define TARGET_BUILTIN_DECL msp430_builtin_decl
2876 void
2877 msp430_expand_prologue (void)
2879 int i, j;
2880 int fs;
2881 /* Always use stack_pointer_rtx instead of calling
2882 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
2883 that there is a single rtx representing the stack pointer,
2884 namely stack_pointer_rtx, and uses == to recognize it. */
2885 rtx sp = stack_pointer_rtx;
2886 rtx p;
2888 if (is_naked_func ())
2890 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2891 examines the output of the gen_prologue() function. */
2892 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2893 return;
2896 emit_insn (gen_prologue_start_marker ());
2898 if (is_critical_func ())
2900 emit_insn (gen_push_intr_state ());
2901 emit_insn (gen_disable_interrupts ());
2903 else if (is_reentrant_func ())
2904 emit_insn (gen_disable_interrupts ());
2906 if (!cfun->machine->computed)
2907 msp430_compute_frame_info ();
2909 if (flag_stack_usage_info)
2910 current_function_static_stack_size = cfun->machine->framesize;
2912 if (crtl->args.pretend_args_size)
2914 rtx note;
2916 gcc_assert (crtl->args.pretend_args_size == 2);
2918 p = emit_insn (gen_grow_and_swap ());
2920 /* Document the stack decrement... */
2921 note = F (gen_rtx_SET (stack_pointer_rtx,
2922 gen_rtx_MINUS (Pmode,
2923 stack_pointer_rtx, GEN_INT (2))));
2924 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2926 /* ...and the establishment of a new location for the return address. */
2927 note = F (gen_rtx_SET (gen_rtx_MEM (Pmode,
2928 gen_rtx_PLUS (Pmode,
2929 stack_pointer_rtx,
2930 GEN_INT (-2))),
2931 pc_rtx));
2932 add_reg_note (p, REG_CFA_OFFSET, note);
2933 F (p);
2936 for (i = 15; i >= 4; i--)
2937 if (cfun->machine->need_to_save[i])
2939 /* We need to save COUNT sequential registers starting from regnum
2940 I. */
2941 int seq, count;
2942 rtx note;
2944 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
2946 count = i - seq;
2948 if (msp430x)
2950 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two
2951 bytes bigger. */
2952 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
2953 GEN_INT (count))));
2955 /* Document the stack decrement as a result of PUSHM. */
2956 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2958 XVECEXP (note, 0, 0)
2959 = F (gen_rtx_SET (stack_pointer_rtx,
2960 gen_rtx_PLUS (Pmode,
2961 stack_pointer_rtx,
2962 GEN_INT (count * (TARGET_LARGE
2963 ? -4 : -2)))));
2965 /* *sp-- = R[i-j] */
2966 /* sp+N R10
2968 sp R4 */
2969 for (j = 0; j < count; j ++)
2971 rtx addr;
2972 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2974 if (ofs)
2975 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2976 else
2977 addr = stack_pointer_rtx;
2979 XVECEXP (note, 0, j + 1) =
2980 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2981 gen_rtx_REG (Pmode, i - j)));
2984 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2985 i -= count - 1;
2987 else
2988 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2991 if (frame_pointer_needed)
2992 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2994 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2996 increment_stack (- fs);
2998 emit_insn (gen_prologue_end_marker ());
3001 void
3002 msp430_expand_epilogue (int is_eh)
3004 int i, j;
3005 int fs;
3006 rtx sp = stack_pointer_rtx;
3007 rtx p;
3008 int helper_n = 0;
3010 if (is_naked_func ())
3012 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
3013 examines the output of the gen_epilogue() function. */
3014 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
3015 return;
3018 if (cfun->machine->need_to_save[10])
3020 /* Check for a helper function. */
3021 helper_n = 7; /* For when the loop below never sees a match. */
3022 for (i = 9; i >= 4; i--)
3023 if (!cfun->machine->need_to_save[i])
3025 helper_n = 10 - i;
3026 for (; i >= 4; i--)
3027 if (cfun->machine->need_to_save[i])
3029 helper_n = 0;
3030 break;
3032 break;
3036 emit_insn (gen_epilogue_start_marker ());
3038 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)),
3039 "main") == 0)
3040 emit_insn (gen_msp430_refsym_need_exit ());
3042 if (is_wakeup_func ())
3043 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
3044 status register current residing on the stack. When this function
3045 executes its RETI instruction the SR will be updated with this saved
3046 value, thus ensuring that the processor is woken up from any low power
3047 state in which it may be residing. */
3048 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
3050 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
3052 increment_stack (fs);
3054 if (is_eh)
3056 /* We need to add the right "SP" register save just after the
3057 regular ones, so that when we pop it off we're in the EH
3058 return frame, not this one. This overwrites our own return
3059 address, but we're not going to be returning anyway. */
3060 rtx r12 = gen_rtx_REG (Pmode, 12);
3061 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
3063 /* R12 will hold the new SP. */
3064 i = cfun->machine->framesize_regs;
3065 emit_move_insn (r12, stack_pointer_rtx);
3066 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
3067 emit_insn (addPmode (r12, r12, GEN_INT (i)));
3068 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode,
3069 stack_pointer_rtx,
3070 i)), r12);
3073 for (i = 4; i <= 15; i++)
3074 if (cfun->machine->need_to_save[i])
3076 /* We need to restore COUNT sequential registers starting from regnum
3077 I. */
3078 int seq;
3079 int count = 1;
3080 int helper_used = 0;
3081 rtx note, addr;
3083 if (msp430x)
3085 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq];
3086 seq++)
3088 count = seq - i;
3091 if (msp430x)
3093 /* Note: With TARGET_LARGE we still use
3094 POPM as POPX.A is two bytes bigger. */
3095 p = F (emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
3096 GEN_INT (count))));
3098 else if (i == 11 - helper_n
3099 && ! msp430_is_interrupt_func ()
3100 && ! is_reentrant_func ()
3101 && ! is_critical_func ()
3102 && crtl->args.pretend_args_size == 0
3103 /* Calling the helper takes as many bytes as the POP;RET
3104 sequence. */
3105 && helper_n > 1
3106 && !is_eh)
3108 p = F (emit_jump_insn (gen_epilogue_helper (GEN_INT (helper_n))));
3109 count = helper_n;
3110 helper_used = 1;
3112 else
3113 p = F (emit_insn (gen_pop (gen_rtx_REG (Pmode, i))));
3115 /* Document the stack increment as a result of POPM. */
3116 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
3118 addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3119 GEN_INT (count * (TARGET_LARGE ? 4 : 2)));
3121 XVECEXP (note, 0, 0) = F (gen_rtx_SET (stack_pointer_rtx, addr));
3124 /* *sp++ = R[i+j] */
3125 /* sp R4
3127 sp+N R10. */
3128 for (j = 0; j < count; j++)
3130 int ofs = j * (TARGET_LARGE ? 4 : 2);
3132 if (ofs)
3133 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
3134 else
3135 addr = stack_pointer_rtx;
3137 XVECEXP (note, 0, j + 1)
3138 = F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
3139 gen_rtx_REG (Pmode, i + j)));
3141 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
3142 i += count - 1;
3144 if (helper_used)
3145 return;
3148 if (is_eh)
3150 /* Also pop SP, which puts us into the EH return frame. Except
3151 that you can't "pop" sp, you have to just load it off the
3152 stack. */
3153 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode,
3154 stack_pointer_rtx));
3157 if (crtl->args.pretend_args_size)
3158 emit_insn (gen_swap_and_shrink ());
3160 if (is_critical_func ())
3161 emit_insn (gen_pop_intr_state ());
3162 else if (is_reentrant_func ())
3163 emit_insn (gen_enable_interrupts ());
3165 emit_jump_insn (gen_msp430_return ());
3168 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
3169 m32c_emit_eh_epilogue. */
3171 msp430_eh_return_stackadj_rtx (void)
3173 if (!cfun->machine->eh_stack_adjust)
3175 rtx sa;
3177 sa = gen_rtx_REG (Pmode, 15);
3178 cfun->machine->eh_stack_adjust = sa;
3180 return cfun->machine->eh_stack_adjust;
3183 /* This function is called before reload, to "fix" the stack in
3184 preparation for an EH return. */
3185 void
3186 msp430_expand_eh_return (rtx eh_handler)
3188 /* These are all Pmode */
3189 rtx ap, sa, ra, tmp;
3191 ap = arg_pointer_rtx;
3192 sa = msp430_eh_return_stackadj_rtx ();
3193 ra = eh_handler;
3195 tmp = ap;
3196 tmp = gen_rtx_PLUS (Pmode, ap, sa);
3197 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
3198 tmp = gen_rtx_MEM (Pmode, tmp);
3199 emit_move_insn (tmp, ra);
3202 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
3203 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
3204 void
3205 msp430_init_dwarf_reg_sizes_extra (tree address)
3207 int i;
3208 rtx addr = expand_normal (address);
3209 rtx mem = gen_rtx_MEM (BLKmode, addr);
3211 /* This needs to match msp430_unwind_word_mode (above). */
3212 if (!msp430x)
3213 return;
3215 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
3217 unsigned int dnum = DWARF_FRAME_REGNUM (i);
3218 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
3220 if (rnum < DWARF_FRAME_REGISTERS)
3222 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
3224 emit_move_insn (adjust_address (mem, QImode, offset),
3225 gen_int_mode (4, QImode));
3230 /* The MSP430 ABI defines a number of helper functions that should be
3231 used for, for example, 32-bit shifts. This function is called to
3232 emit such a function, using the table above to optimize some
3233 cases. */
3234 void
3235 msp430_expand_helper (rtx *operands, const char *helper_name,
3236 bool const_variants)
3238 rtx c, fusage, fsym;
3239 char *helper_const = NULL;
3240 int arg1 = 12;
3241 int arg2 = 13;
3242 int arg1sz = 1;
3243 machine_mode arg0mode = GET_MODE (operands[0]);
3244 machine_mode arg1mode = GET_MODE (operands[1]);
3245 machine_mode arg2mode = GET_MODE (operands[2]);
3246 int expand_mpy = strncmp (helper_name, "__mspabi_mpy",
3247 sizeof ("__mspabi_mpy") - 1) == 0;
3248 /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a
3249 hwmpy function. */
3250 gcc_assert (!(expand_mpy && const_variants));
3252 if (arg1mode != VOIDmode && arg2mode != VOIDmode)
3253 /* Modes of arguments must be equal if not constants. */
3254 gcc_assert (arg1mode == arg2mode);
3256 if (arg1mode == VOIDmode)
3257 arg1mode = arg0mode;
3258 if (arg2mode == VOIDmode)
3259 arg2mode = arg0mode;
3261 if (arg1mode == SImode)
3263 arg2 = 14;
3264 arg1sz = 2;
3266 else if (arg1mode == DImode)
3268 arg1 = 8;
3269 arg1sz = 4;
3270 arg2 = 12;
3273 /* Use the "const_variant" of a shift library function if requested.
3274 These are faster, but have larger code size. */
3275 if (const_variants
3276 && CONST_INT_P (operands[2])
3277 && INTVAL (operands[2]) >= 1
3278 && INTVAL (operands[2]) <= 15)
3280 /* Note that the INTVAL is limited in value and length by the conditional
3281 above. */
3282 int len = strlen (helper_name) + 4;
3283 helper_const = (char *) xmalloc (len);
3284 snprintf (helper_const, len, "%s_%d", helper_name,
3285 (int) INTVAL (operands[2]));
3288 /* Setup the arguments to the helper function. */
3289 emit_move_insn (gen_rtx_REG (arg1mode, arg1),
3290 operands[1]);
3291 if (!helper_const)
3292 emit_move_insn (gen_rtx_REG (arg2mode, arg2),
3293 operands[2]);
3295 if (expand_mpy)
3297 if (msp430_use_f5_series_hwmult ())
3298 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3299 "_f5hw", NULL));
3300 else if (msp430_use_32bit_hwmult ())
3302 /* When the arguments are 16-bits, the 16-bit hardware multiplier is
3303 used. */
3304 if (arg1mode == HImode)
3305 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3306 "_hw", NULL));
3307 else
3308 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3309 "_hw32", NULL));
3311 else if (msp430_use_16bit_hwmult ())
3312 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3313 "_hw", NULL));
3314 else
3315 fsym = gen_rtx_SYMBOL_REF (VOIDmode, helper_name);
3317 else
3318 fsym = gen_rtx_SYMBOL_REF (VOIDmode,
3319 helper_const ? helper_const : helper_name);
3321 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), fsym, GEN_INT (0));
3323 c = emit_call_insn (c);
3324 RTL_CONST_CALL_P (c) = 1;
3326 /* Add register usage information for the arguments to the call. */
3327 fusage = NULL;
3328 use_regs (&fusage, arg1, arg1sz);
3329 if (!helper_const)
3331 /* If we are expanding a shift, we only need to use the low register
3332 for the shift amount. */
3333 if (!expand_mpy)
3334 use_regs (&fusage, arg2, 1);
3335 else
3336 use_regs (&fusage, arg2, arg1sz);
3338 add_function_usage_to (c, fusage);
3340 emit_move_insn (operands[0],
3341 /* Return value will always start in R12. */
3342 gen_rtx_REG (arg0mode, 12));
3345 /* Return TRUE if the helper function should be used and FALSE if the shifts
3346 insns should be emitted inline. */
3347 static bool
3348 use_helper_for_const_shift (machine_mode mode, HOST_WIDE_INT amt)
3350 const int default_inline_shift = 4;
3351 /* We initialize the option to 65 so we know if the user set it or not. */
3352 int user_set_max_inline = (msp430_max_inline_shift == 65 ? 0 : 1);
3353 int max_inline = (user_set_max_inline ? msp430_max_inline_shift
3354 : default_inline_shift);
3355 /* 32-bit shifts are roughly twice as costly as 16-bit shifts so we adjust
3356 the heuristic accordingly. */
3357 int max_inline_32 = max_inline / 2;
3359 if (mode == E_DImode)
3360 return true;
3362 /* Don't use helpers for these modes on 430X, when optimizing for speed, or
3363 when emitting a small number of insns. */
3364 if ((mode == E_QImode || mode == E_HImode || mode == E_PSImode)
3365 && (msp430x
3366 /* If the user set max_inline then we always obey that number.
3367 Otherwise we always emit the shifts inline at -O2 and above. */
3368 || amt <= max_inline
3369 || (!user_set_max_inline
3370 && (optimize >= 2 && !optimize_size))))
3371 return false;
3373 /* 430 and 430X codegen for SImode shifts is the same.
3374 Set a hard limit of 15 for the number of shifts that will be emitted
3375 inline by default, even at -O2 and above, to prevent code size
3376 explosion. */
3377 if (mode == E_SImode
3378 && (amt <= max_inline_32
3379 || (!user_set_max_inline
3380 && (optimize >= 2 && !optimize_size)
3381 && amt <= 15)))
3382 return false;
3384 return true;
3387 /* For shift operations which will use an mspabi helper function, setup the
3388 call to msp430_expand helper. Return 1 to indicate we have finished with
3389 this insn and invoke "DONE".
3390 Otherwise return 0 to indicate the insn should fallthrough.
3391 Never FAIL. */
3393 msp430_expand_shift (enum rtx_code code, machine_mode mode, rtx *operands)
3395 /* Always use the helper function when the shift amount is not a
3396 constant. */
3397 if (!CONST_INT_P (operands[2])
3398 || mode == E_DImode
3399 || use_helper_for_const_shift (mode, INTVAL (operands[2])))
3401 const char *helper_name = NULL;
3402 /* The const variants of mspabi shifts have significantly larger code
3403 size than the generic version, so use the generic version if
3404 optimizing for size. */
3405 bool const_variant = !optimize_size;
3406 switch (mode)
3408 case E_HImode:
3409 helper_name = (code == ASHIFT ? "__mspabi_slli" :
3410 (code == ASHIFTRT ? "__mspabi_srai" :
3411 (code == LSHIFTRT ? "__mspabi_srli" :
3412 NULL)));
3413 break;
3414 case E_PSImode:
3415 helper_name = (code == ASHIFT ? "__gnu_mspabi_sllp" :
3416 (code == ASHIFTRT ? "__gnu_mspabi_srap" :
3417 (code == LSHIFTRT ? "__gnu_mspabi_srlp" :
3418 NULL)));
3419 /* No const variant for PSImode shifts FIXME. */
3420 const_variant = false;
3421 break;
3422 case E_SImode:
3423 helper_name = (code == ASHIFT ? "__mspabi_slll" :
3424 (code == ASHIFTRT ? "__mspabi_sral" :
3425 (code == LSHIFTRT ? "__mspabi_srll" :
3426 NULL)));
3427 break;
3428 case E_DImode:
3429 helper_name = (code == ASHIFT ? "__mspabi_sllll" :
3430 (code == ASHIFTRT ? "__mspabi_srall" :
3431 (code == LSHIFTRT ? "__mspabi_srlll" :
3432 NULL)));
3433 /* No const variant for DImode shifts. */
3434 const_variant = false;
3435 break;
3436 default:
3437 gcc_unreachable ();
3438 break;
3440 gcc_assert (helper_name);
3441 msp430_expand_helper (operands, helper_name, const_variant);
3442 return 1;
3444 /* When returning 0, there must be an insn to match the RTL pattern
3445 otherwise there will be an unrecognizeable insn. */
3446 return 0;
3449 /* Helper function to emit a sequence of shift instructions. The amount of
3450 shift instructions to emit is in OPERANDS[2].
3451 For 430 we output copies of identical inline shifts for all modes.
3452 For 430X it is inneficient to do so for any modes except SI and DI, since we
3453 can make use of R*M insns or RPT with 430X insns, so this function is only
3454 used for SImode in that case. */
3456 msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode,
3457 rtx *operands, bool return_length)
3459 int i;
3460 int amt;
3461 int max_shift = GET_MODE_BITSIZE (mode) - 1;
3462 int length = 0;
3464 gcc_assert (CONST_INT_P (operands[2]));
3465 amt = INTVAL (operands[2]);
3467 if (amt == 0 || amt > max_shift)
3469 if (return_length)
3470 return 0;
3471 switch (code)
3473 case ASHIFT:
3474 output_asm_insn ("# ignored undefined behaviour left shift "
3475 "of %1 by %2", operands);
3476 break;
3477 case ASHIFTRT:
3478 output_asm_insn ("# ignored undefined behaviour arithmetic right "
3479 "shift of %1 by %2", operands);
3480 break;
3481 case LSHIFTRT:
3482 output_asm_insn ("# ignored undefined behaviour logical right shift "
3483 "of %1 by %2", operands);
3484 break;
3485 default:
3486 gcc_unreachable ();
3488 return 0;
3491 if (code == ASHIFT)
3493 if (!msp430x && mode == HImode)
3495 if (return_length)
3496 length = 2 + (MEM_P (operands[0]) ? 2 : 0);
3497 else
3498 for (i = 0; i < amt; i++)
3499 output_asm_insn ("RLA.W\t%0", operands);
3501 else if (mode == SImode)
3503 if (return_length)
3504 length = 4 + (MEM_P (operands[0]) ? 4 : 0)
3505 + (4 * msp430x_insn_required (operands[0]));
3506 else
3507 for (i = 0; i < amt; i++)
3508 output_asm_insn ("RLA%X0.W\t%L0 { RLC%X0.W\t%H0", operands);
3510 else
3511 /* Catch unhandled cases. */
3512 gcc_unreachable ();
3514 else if (code == ASHIFTRT)
3516 if (!msp430x && mode == HImode)
3518 if (return_length)
3519 length = 2 + (MEM_P (operands[0]) ? 2 : 0);
3520 else
3521 for (i = 0; i < amt; i++)
3522 output_asm_insn ("RRA.W\t%0", operands);
3524 else if (mode == SImode)
3526 if (return_length)
3527 length = 4 + (MEM_P (operands[0]) ? 4 : 0)
3528 + (4 * msp430x_insn_required (operands[0]));
3529 else
3530 for (i = 0; i < amt; i++)
3531 output_asm_insn ("RRA%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
3533 else
3534 gcc_unreachable ();
3536 else if (code == LSHIFTRT)
3538 if (!msp430x && mode == HImode)
3540 if (return_length)
3541 length = 4 + (MEM_P (operands[0]) ? 2 : 0);
3542 else
3543 for (i = 0; i < amt; i++)
3544 output_asm_insn ("CLRC { RRC.W\t%0", operands);
3546 else if (mode == SImode)
3548 if (return_length)
3549 length = 6 + (MEM_P (operands[0]) ? 4 : 0)
3550 + (4 * msp430x_insn_required (operands[0]));
3551 else
3552 for (i = 0; i < amt; i++)
3553 output_asm_insn ("CLRC { RRC%X0.W\t%H0 { RRC%X0.W\t%L0",
3554 operands);
3556 /* FIXME: Why doesn't "RRUX.W\t%H0 { RRC%X0.W\t%L0" work for msp430x?
3557 It causes execution timeouts e.g. pr41963.c. */
3558 #if 0
3559 else if (msp430x && mode == SImode)
3561 if (return_length)
3562 length = 2;
3563 else
3564 for (i = 0; i < amt; i++)
3565 output_asm_insn ("RRUX.W\t%H0 { RRC%X0.W\t%L0", operands);
3567 #endif
3568 else
3569 gcc_unreachable ();
3571 return length * amt;
3574 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
3575 void
3576 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
3578 /* constants we're looking for, not constants which are allowed. */
3579 int const_op_idx = 1;
3581 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
3582 const_op_idx = 2;
3584 if (GET_CODE (operands[const_op_idx]) != REG
3585 && GET_CODE (operands[const_op_idx]) != MEM)
3586 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
3589 /* Simplify_gen_subreg() doesn't handle memory references the way we
3590 need it to below, so we use this function for when we must get a
3591 valid subreg in a "natural" state. */
3593 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
3595 rtx rv;
3596 gcc_assert (mode == HImode);
3598 if (GET_CODE (r) == SUBREG
3599 && SUBREG_BYTE (r) == 0)
3601 rtx ireg = SUBREG_REG (r);
3602 machine_mode imode = GET_MODE (ireg);
3604 /* special case for (HI (SI (PSI ...), 0)) */
3605 if (imode == PSImode
3606 && mode == HImode
3607 && byte == 0)
3608 rv = gen_rtx_SUBREG (mode, ireg, byte);
3609 else
3610 rv = simplify_gen_subreg (mode, ireg, imode, byte);
3612 else if (GET_CODE (r) == MEM)
3614 /* When byte == 2, we can be certain that we were already called with an
3615 identical rtx with byte == 0. So we don't need to do anything to
3616 get a 2 byte offset of a (mem (post_inc)) rtx, since the address has
3617 already been offset by the post_inc itself. */
3618 if (GET_CODE (XEXP (r, 0)) == POST_INC && byte == 2)
3619 byte = 0;
3620 rv = adjust_address (r, mode, byte);
3622 else if (GET_CODE (r) == SYMBOL_REF
3623 && (byte == 0 || byte == 2)
3624 && mode == HImode)
3626 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
3627 rv = gen_rtx_CONST (HImode, r);
3629 else
3630 rv = simplify_gen_subreg (mode, r, omode, byte);
3632 if (!rv)
3633 gcc_unreachable ();
3635 return rv;
3639 msp430_split_addsi (rtx *operands)
3641 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
3642 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
3643 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
3644 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
3645 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
3646 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
3648 /* BZ 64160: Do not use this splitter when the dest partially overlaps the
3649 source. */
3650 if (reg_overlap_mentioned_p (operands[3], operands[7])
3651 || reg_overlap_mentioned_p (operands[3], operands[8]))
3652 return 1;
3654 if (GET_CODE (operands[5]) == CONST_INT)
3655 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
3656 /* Handle post_inc, for example:
3657 (set (reg:SI)
3658 (plus:SI (reg:SI)
3659 (mem:SI (post_inc:PSI (reg:PSI))))). */
3660 else if (MEM_P (operands[5]) && GET_CODE (XEXP (operands[5], 0)) == POST_INC)
3662 /* Strip out the post_inc from (mem (post_inc (reg))). */
3663 operands[9] = XEXP (XEXP (operands[5], 0), 0);
3664 operands[9] = gen_rtx_MEM (HImode, operands[9]);
3665 /* Then zero extend as normal. */
3666 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[9]);
3668 else
3669 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
3670 return 0;
3673 /* Called by movsi_x to generate the HImode operands. */
3674 void
3675 msp430_split_movsi (rtx *operands)
3677 rtx op00, op02, op10, op12;
3679 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
3680 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
3682 if (GET_CODE (operands[1]) == CONST
3683 || GET_CODE (operands[1]) == SYMBOL_REF)
3685 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
3686 GEN_INT (0));
3687 op10 = gen_rtx_CONST (HImode, op10);
3688 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
3689 GEN_INT (16));
3690 op12 = gen_rtx_CONST (HImode, op12);
3692 else
3694 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
3695 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
3698 if (rtx_equal_p (operands[0], operands[1]))
3700 operands[2] = op02;
3701 operands[4] = op12;
3702 operands[3] = op00;
3703 operands[5] = op10;
3705 else if (rtx_equal_p (op00, op12)
3706 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
3707 || (REG_P (op00) && reg_mentioned_p (op00, op10))
3708 /* Or storing (rN) into mem (rN). */
3709 || (REG_P (op10) && reg_mentioned_p (op10, op00)))
3711 operands[2] = op02;
3712 operands[4] = op12;
3713 operands[3] = op00;
3714 operands[5] = op10;
3716 else
3718 operands[2] = op00;
3719 operands[4] = op10;
3720 operands[3] = op02;
3721 operands[5] = op12;
3726 /* The MSPABI specifies the names of various helper functions, many of
3727 which are compatible with GCC's helpers. This table maps the GCC
3728 name to the MSPABI name. */
3729 static const struct
3731 char const * const gcc_name;
3732 char const * const ti_name;
3734 helper_function_name_mappings[] =
3736 /* Floating point to/from integer conversions. */
3737 { "__truncdfsf2", "__mspabi_cvtdf" },
3738 { "__extendsfdf2", "__mspabi_cvtfd" },
3739 { "__fixdfhi", "__mspabi_fixdi" },
3740 { "__fixdfsi", "__mspabi_fixdli" },
3741 { "__fixdfdi", "__mspabi_fixdlli" },
3742 { "__fixunsdfhi", "__mspabi_fixdu" },
3743 { "__fixunsdfsi", "__mspabi_fixdul" },
3744 { "__fixunsdfdi", "__mspabi_fixdull" },
3745 { "__fixsfhi", "__mspabi_fixfi" },
3746 { "__fixsfsi", "__mspabi_fixfli" },
3747 { "__fixsfdi", "__mspabi_fixflli" },
3748 { "__fixunsfhi", "__mspabi_fixfu" },
3749 { "__fixunsfsi", "__mspabi_fixful" },
3750 { "__fixunsfdi", "__mspabi_fixfull" },
3751 { "__floathisf", "__mspabi_fltif" },
3752 { "__floatsisf", "__mspabi_fltlif" },
3753 { "__floatdisf", "__mspabi_fltllif" },
3754 { "__floathidf", "__mspabi_fltid" },
3755 { "__floatsidf", "__mspabi_fltlid" },
3756 { "__floatdidf", "__mspabi_fltllid" },
3757 { "__floatunhisf", "__mspabi_fltuf" },
3758 { "__floatunsisf", "__mspabi_fltulf" },
3759 { "__floatundisf", "__mspabi_fltullf" },
3760 { "__floatunhidf", "__mspabi_fltud" },
3761 { "__floatunsidf", "__mspabi_fltuld" },
3762 { "__floatundidf", "__mspabi_fltulld" },
3764 /* Floating point comparisons. */
3765 /* GCC uses individual functions for each comparison, TI uses one
3766 compare <=> function. */
3768 /* Floating point arithmetic. */
3769 { "__adddf3", "__mspabi_addd" },
3770 { "__addsf3", "__mspabi_addf" },
3771 { "__divdf3", "__mspabi_divd" },
3772 { "__divsf3", "__mspabi_divf" },
3773 { "__muldf3", "__mspabi_mpyd" },
3774 { "__mulsf3", "__mspabi_mpyf" },
3775 { "__subdf3", "__mspabi_subd" },
3776 { "__subsf3", "__mspabi_subf" },
3777 /* GCC does not use helper functions for negation. */
3779 /* Integer multiply, divide, remainder. */
3780 { "__mulhi3", "__mspabi_mpyi" },
3781 { "__mulsi3", "__mspabi_mpyl" },
3782 { "__muldi3", "__mspabi_mpyll" },
3783 #if 0
3784 /* Clarify signed vs unsigned first. */
3785 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
3786 (yet?) */
3787 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
3788 (yet?) */
3789 #endif
3791 { "__divhi3", "__mspabi_divi" },
3792 { "__divsi3", "__mspabi_divli" },
3793 { "__divdi3", "__mspabi_divlli" },
3794 { "__udivhi3", "__mspabi_divu" },
3795 { "__udivsi3", "__mspabi_divul" },
3796 { "__udivdi3", "__mspabi_divull" },
3797 { "__modhi3", "__mspabi_remi" },
3798 { "__modsi3", "__mspabi_remli" },
3799 { "__moddi3", "__mspabi_remlli" },
3800 { "__umodhi3", "__mspabi_remu" },
3801 { "__umodsi3", "__mspabi_remul" },
3802 { "__umoddi3", "__mspabi_remull" },
3804 /* Bitwise operations. */
3805 /* Rotation - no rotation support yet. */
3806 /* Logical left shift - gcc already does these itself. */
3807 /* Arithmetic left shift - gcc already does these itself. */
3808 /* Arithmetic right shift - gcc already does these itself. */
3810 { NULL, NULL }
3813 /* Returns true if the current MCU supports an F5xxx series
3814 hardware multiper. */
3816 bool
3817 msp430_use_f5_series_hwmult (void)
3819 static const char * cached_match = NULL;
3820 static bool cached_result;
3822 if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
3823 return true;
3825 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3826 return false;
3828 if (target_mcu == cached_match)
3829 return cached_result;
3831 cached_match = target_mcu;
3833 if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
3834 return cached_result = true;
3835 if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
3836 return cached_result = true;
3837 if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
3838 return cached_result = true;
3840 msp430_extract_mcu_data (target_mcu);
3842 if (extracted_mcu_data.name != NULL)
3843 return cached_result = extracted_mcu_data.hwmpy == 8;
3845 return cached_result = false;
3848 /* Returns true if the current MCU has a second generation
3849 32-bit hardware multiplier. */
3851 static bool
3852 msp430_use_32bit_hwmult (void)
3854 static const char * cached_match = NULL;
3855 static bool cached_result;
3857 if (msp430_hwmult_type == MSP430_HWMULT_LARGE)
3858 return true;
3860 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3861 return false;
3863 if (target_mcu == cached_match)
3864 return cached_result;
3866 cached_match = target_mcu;
3868 msp430_extract_mcu_data (target_mcu);
3869 if (extracted_mcu_data.name != NULL)
3870 return cached_result = extracted_mcu_data.hwmpy == 4;
3872 return cached_result = false;
3875 /* Returns true if the current MCU has a first generation
3876 16-bit hardware multiplier. */
3878 static bool
3879 msp430_use_16bit_hwmult (void)
3881 static const char * cached_match = NULL;
3882 static bool cached_result;
3884 if (msp430_hwmult_type == MSP430_HWMULT_SMALL)
3885 return true;
3887 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3888 return false;
3890 if (target_mcu == cached_match)
3891 return cached_result;
3893 cached_match = target_mcu;
3895 msp430_extract_mcu_data (target_mcu);
3896 if (extracted_mcu_data.name != NULL)
3897 return cached_result = (extracted_mcu_data.hwmpy == 1
3898 || extracted_mcu_data.hwmpy == 2);
3900 return cached_result = false;
3903 /* Returns true if the current MCU does not have a
3904 hardware multiplier of any kind. */
3906 bool
3907 msp430_has_hwmult (void)
3909 static const char * cached_match = NULL;
3910 static bool cached_result;
3912 if (msp430_hwmult_type == MSP430_HWMULT_NONE)
3913 return false;
3915 /* TRUE for any other explicit hwmult specified. */
3916 if (msp430_hwmult_type != MSP430_HWMULT_AUTO)
3917 return true;
3919 /* Now handle -mhwmult=auto. */
3920 if (target_mcu == NULL)
3921 return false;
3923 if (target_mcu == cached_match)
3924 return cached_result;
3926 cached_match = target_mcu;
3928 msp430_extract_mcu_data (target_mcu);
3929 if (extracted_mcu_data.name != NULL)
3930 return cached_result = extracted_mcu_data.hwmpy != 0;
3932 /* If we do not recognise the MCU name, we assume that it does not support
3933 any kind of hardware multiply - this is the safest assumption to make. */
3934 return cached_result = false;
3937 /* This function does the same as the default, but it will replace GCC
3938 function names with the MSPABI-specified ones. */
3940 void
3941 msp430_output_labelref (FILE *file, const char *name)
3943 int i;
3945 for (i = 0; helper_function_name_mappings[i].gcc_name; i++)
3946 if (strcmp (helper_function_name_mappings[i].gcc_name, name) == 0)
3948 name = helper_function_name_mappings[i].ti_name;
3949 break;
3952 if (user_label_prefix[0] != 0)
3953 fputs (user_label_prefix, file);
3955 fputs (name, file);
3958 /* Common code for msp430_print_operand... */
3960 static void
3961 msp430_print_operand_raw (FILE * file, rtx op)
3963 HOST_WIDE_INT i;
3965 switch (GET_CODE (op))
3967 case REG:
3968 fprintf (file, "%s", reg_names[REGNO (op)]);
3969 break;
3971 case CONST_INT:
3972 i = INTVAL (op);
3973 if (TARGET_ASM_HEX)
3974 fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
3975 else
3976 fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
3977 break;
3979 case CONST:
3980 case PLUS:
3981 case MINUS:
3982 case SYMBOL_REF:
3983 case LABEL_REF:
3984 output_addr_const (file, op);
3985 break;
3987 default:
3988 print_rtl (file, op);
3989 break;
3993 #undef TARGET_ASM_ALIGNED_PSI_OP
3994 #define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
3995 #undef TARGET_ASM_UNALIGNED_PSI_OP
3996 #define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
3998 #undef TARGET_PRINT_OPERAND_ADDRESS
3999 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
4001 /* Output to stdio stream FILE the assembler syntax for an
4002 instruction operand that is a memory reference whose address
4003 is ADDR. */
4005 static void
4006 msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
4008 switch (GET_CODE (addr))
4010 case PLUS:
4011 msp430_print_operand_raw (file, XEXP (addr, 1));
4012 gcc_assert (REG_P (XEXP (addr, 0)));
4013 fprintf (file, "(%s)", reg_names[REGNO (XEXP (addr, 0))]);
4014 return;
4016 case REG:
4017 fprintf (file, "@");
4018 break;
4020 case POST_INC:
4021 fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
4022 return;
4024 case CONST:
4025 case CONST_INT:
4026 case SYMBOL_REF:
4027 case LABEL_REF:
4028 fprintf (file, "&");
4029 break;
4031 default:
4032 break;
4035 msp430_print_operand_raw (file, addr);
4038 /* We can only allow signed 15-bit indexes i.e. +/-32K. */
4039 static bool
4040 msp430_check_index_not_high_mem (rtx op)
4042 if (CONST_INT_P (op)
4043 && IN_RANGE (INTVAL (op), HOST_WIDE_INT_M1U << 15, (1 << 15) - 1))
4044 return true;
4045 return false;
4048 /* If this returns true, we don't need a 430X insn. */
4049 static bool
4050 msp430_check_plus_not_high_mem (rtx op)
4052 if (GET_CODE (op) != PLUS)
4053 return false;
4054 rtx op0 = XEXP (op, 0);
4055 rtx op1 = XEXP (op, 1);
4056 if (SYMBOL_REF_P (op0)
4057 && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM)
4058 && msp430_check_index_not_high_mem (op1))
4059 return true;
4060 return false;
4063 /* Determine whether an RTX is definitely not a MEM referencing an address in
4064 the upper memory region. Returns true if we've decided the address will be
4065 in the lower memory region, or the RTX is not a MEM. Returns false
4066 otherwise.
4067 The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
4068 involving a symbol_ref here. */
4069 bool
4070 msp430_op_not_in_high_mem (rtx op)
4072 rtx op0;
4074 if (!TARGET_LARGE || !MEM_P (op))
4075 return true;
4077 op0 = XEXP (op, 0);
4079 if (SYMBOL_REF_P (op0) && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM))
4080 /* msp430_encode_section_info decided this mem will be in lower
4081 memory. */
4082 return true;
4084 /* Check possibilites for (mem (plus)).
4085 e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2. */
4086 if (msp430_check_plus_not_high_mem (op0)
4087 || ((GET_CODE (op0) == CONST)
4088 && msp430_check_plus_not_high_mem (XEXP (op0, 0))))
4089 return true;
4091 /* An absolute 16-bit address is allowed. */
4092 if ((CONST_INT_P (op0) && (IN_RANGE (INTVAL (op0), 0, (1 << 16) - 1))))
4093 return true;
4095 /* Return false when undecided. */
4096 return false;
4099 /* Based on the operand OP, is a 430X insn required to handle it?
4100 There are only 3 conditions for which a 430X insn is required:
4101 - PSImode operand
4102 - memory reference to a symbol which could be in upper memory
4103 (so its address is > 0xFFFF)
4104 - absolute address which has VOIDmode, i.e. (mem:HI (const_int))
4105 Use a 430 insn if none of these conditions are true. */
4106 bool
4107 msp430x_insn_required (rtx op)
4109 return (GET_MODE (op) == PSImode
4110 || !msp430_op_not_in_high_mem (op));
4113 #undef TARGET_PRINT_OPERAND
4114 #define TARGET_PRINT_OPERAND msp430_print_operand
4116 /* A Select low 16-bits of the constant/register/memory operand.
4117 B Select high 16-bits of the constant/register/memory
4118 operand.
4119 C Select bits 32-47 of the constant/register/memory operand.
4120 D Select bits 48-63 of the constant/register/memory operand.
4121 H Equivalent to @code{B} (for backwards compatibility).
4122 I Print the inverse (logical @code{NOT}) of the constant
4123 value.
4124 J Print an integer without a @code{#} prefix.
4125 L Equivalent to @code{A} (for backwards compatibility).
4126 O Offset of the current frame from the top of the stack.
4127 Q Use the @code{A} instruction postfix.
4128 R Inverse of condition code, for unsigned comparisons.
4129 W Subtract 16 from the constant value.
4130 X Use the @code{X} instruction postfix.
4131 Y Subtract 4 from the constant value.
4132 Z Subtract 1 from the constant value.
4133 b Append @code{.B}, @code{.W} or @code{.A} to the
4134 instruction, depending on the mode.
4135 d Offset 1 byte of a memory reference or constant value.
4136 e Offset 3 bytes of a memory reference or constant value.
4137 f Offset 5 bytes of a memory reference or constant value.
4138 g Offset 7 bytes of a memory reference or constant value.
4139 p Print the value of 2, raised to the power of the given
4140 constant. Used to select the specified bit position.
4141 r Inverse of condition code, for signed comparisons.
4142 x Equivialent to @code{X}, but only for pointers. */
4144 static void
4145 msp430_print_operand (FILE * file, rtx op, int letter)
4147 rtx addr;
4148 /* These are used by the 'A', 'B', 'C', 'D', 'd', 'e', 'f' and 'g' modifiers
4149 to describe how to process the operand to get the requested value. */
4150 int mem_off = 0;
4151 int reg_off = 0;
4152 int const_shift = 0;
4154 /* We can't use c, n, a, or l. */
4155 switch (letter)
4157 case 'Z':
4158 gcc_assert (CONST_INT_P (op));
4159 /* Print the constant value, less one. */
4160 fprintf (file, "#%ld", (long) (INTVAL (op) - 1));
4161 return;
4162 case 'Y':
4163 gcc_assert (CONST_INT_P (op));
4164 /* Print the constant value, less four. */
4165 fprintf (file, "#%ld", (long) (INTVAL (op) - 4));
4166 return;
4167 case 'W':
4168 gcc_assert (CONST_INT_P (op));
4169 /* Print the constant value, less 16. */
4170 fprintf (file, "#%ld", (long) (INTVAL (op) - 16));
4171 return;
4172 case 'I':
4173 if (GET_CODE (op) == CONST_INT)
4175 /* Inverse of constants */
4176 int i = INTVAL (op);
4177 fprintf (file, "%d", ~i);
4178 return;
4180 op = XEXP (op, 0);
4181 break;
4182 case 'r': /* Conditional jump where the condition is reversed. */
4183 switch (GET_CODE (op))
4185 case EQ: fprintf (file, "NE"); break;
4186 case NE: fprintf (file, "EQ"); break;
4187 case GEU: fprintf (file, "LO"); break;
4188 case LTU: fprintf (file, "HS"); break;
4189 case GE: fprintf (file, "L"); break;
4190 case LT: fprintf (file, "GE"); break;
4191 /* Assume these have reversed operands. */
4192 case GTU: fprintf (file, "HS"); break;
4193 case LEU: fprintf (file, "LO"); break;
4194 case GT: fprintf (file, "GE"); break;
4195 case LE: fprintf (file, "L"); break;
4196 default:
4197 msp430_print_operand_raw (file, op);
4198 break;
4200 return;
4201 case 'R': /* Conditional jump where the operands are reversed. */
4202 switch (GET_CODE (op))
4204 case GTU: fprintf (file, "LO"); break;
4205 case LEU: fprintf (file, "HS"); break;
4206 case GT: fprintf (file, "L"); break;
4207 case LE: fprintf (file, "GE"); break;
4208 default:
4209 msp430_print_operand_raw (file, op);
4210 break;
4212 return;
4213 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
4214 gcc_assert (CONST_INT_P (op));
4215 fprintf (file, "#%d", 1 << INTVAL (op));
4216 return;
4217 case 'b':
4218 switch (GET_MODE (op))
4220 case E_QImode: fprintf (file, ".B"); return;
4221 case E_HImode: fprintf (file, ".W"); return;
4222 case E_PSImode: fprintf (file, ".A"); return;
4223 case E_SImode: fprintf (file, ".A"); return;
4224 default:
4225 return;
4227 case 'd': case 'e': case 'f': case 'g':
4228 if (REG_P (op))
4230 output_operand_lossage ("%%d, %%e, %%f, %%g operand modifiers are "
4231 "for memory references or constant values "
4232 "only");
4233 return;
4235 /* fallthru */
4236 case 'B': case 'H': /* high half */
4237 case 'C':
4238 case 'D':
4239 switch (letter)
4241 case 'd':
4242 mem_off = 1;
4243 const_shift = 8;
4244 break;
4245 case 'B':
4246 case 'H':
4247 mem_off = 2;
4248 reg_off = 1;
4249 const_shift = 16;
4250 break;
4251 case 'e':
4252 mem_off = 3;
4253 const_shift = 24;
4254 break;
4255 case 'C':
4256 mem_off = 4;
4257 reg_off = 2;
4258 const_shift = 32;
4259 break;
4260 case 'f':
4261 mem_off = 5;
4262 const_shift = 40;
4263 break;
4264 case 'D':
4265 mem_off = 6;
4266 reg_off = 3;
4267 const_shift = 48;
4268 break;
4269 case 'g':
4270 mem_off = 7;
4271 const_shift = 56;
4272 break;
4273 default:
4274 gcc_unreachable ();
4275 break;
4277 /* fallthru */
4278 case 'A': case 'L': /* Low half. */
4279 switch (GET_CODE (op))
4281 case MEM:
4282 /* We don't need to adjust the address for post_inc. */
4283 op = adjust_address (op, Pmode,
4284 (GET_CODE (XEXP (op, 0)) == POST_INC)
4285 ? 0 : mem_off);
4286 break;
4287 case REG:
4288 op = gen_rtx_REG (Pmode, REGNO (op) + reg_off);
4289 break;
4290 case CONST_INT:
4291 op = GEN_INT (((long long) INTVAL (op) >> const_shift) & 0xffff);
4292 letter = 0;
4293 break;
4294 default:
4295 /* If you get here, figure out a test case :-) */
4296 gcc_unreachable ();
4298 break;
4300 case 'X':
4301 /* This is used to turn, for example, an ADD opcode into an ADDX
4302 opcode when we're using 20-bit addresses.
4303 This can be used for insns which have only one operand which might be
4304 a mem.
4305 If an insn has two different operands which could be memory operands,
4306 then the "Yx" constraint must be used to determine if the X suffix is
4307 required by checking both operands. */
4308 if (GET_MODE (op) == PSImode
4309 || !msp430_op_not_in_high_mem (op))
4310 fprintf (file, "X");
4311 return;
4313 case 'x':
4314 /* Similarly, but only for PSImodes. BIC, and other insn patterns using
4315 the QHI mode iterator (which includes, QI, HI, and PSImode) use
4316 this. */
4317 if (GET_MODE (op) == PSImode)
4318 fprintf (file, "X");
4319 return;
4321 case 'Q':
4322 /* Likewise, for BR -> BRA. */
4323 if (TARGET_LARGE)
4324 fprintf (file, "A");
4325 return;
4327 case 'O':
4328 /* Computes the offset to the top of the stack for the current frame.
4329 This has to be done here rather than in, say, msp430_expand_builtin()
4330 because builtins are expanded before the frame layout is
4331 determined. */
4332 fprintf (file, "%d",
4333 msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
4334 STACK_POINTER_REGNUM)
4335 - (TARGET_LARGE ? 4 : 2));
4336 return;
4338 case 'J':
4339 gcc_assert (GET_CODE (op) == CONST_INT);
4340 case 0:
4341 break;
4342 default:
4343 output_operand_lossage ("invalid operand prefix");
4344 return;
4347 switch (GET_CODE (op))
4349 case REG:
4350 msp430_print_operand_raw (file, op);
4351 break;
4353 case MEM:
4354 addr = XEXP (op, 0);
4355 msp430_print_operand_addr (file, GET_MODE (op), addr);
4356 break;
4358 case CONST:
4359 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
4361 op = XEXP (op, 0);
4362 switch (INTVAL (XEXP (op, 2)))
4364 case 0:
4365 fprintf (file, "#lo (");
4366 msp430_print_operand_raw (file, XEXP (op, 0));
4367 fprintf (file, ")");
4368 break;
4370 case 16:
4371 fprintf (file, "#hi (");
4372 msp430_print_operand_raw (file, XEXP (op, 0));
4373 fprintf (file, ")");
4374 break;
4376 default:
4377 output_operand_lossage ("invalid zero extract");
4378 break;
4380 break;
4382 /* Fall through. */
4383 case CONST_INT:
4384 case SYMBOL_REF:
4385 case LABEL_REF:
4386 if (letter == 0)
4387 fprintf (file, "#");
4388 msp430_print_operand_raw (file, op);
4389 break;
4391 case EQ: fprintf (file, "EQ"); break;
4392 case NE: fprintf (file, "NE"); break;
4393 case GEU: fprintf (file, "HS"); break;
4394 case LTU: fprintf (file, "LO"); break;
4395 case GE: fprintf (file, "GE"); break;
4396 case LT: fprintf (file, "L"); break;
4398 default:
4399 print_rtl (file, op);
4400 break;
4405 /* Frame stuff. */
4408 msp430_return_addr_rtx (int count)
4410 int ra_size;
4411 if (count)
4412 return NULL_RTX;
4414 ra_size = TARGET_LARGE ? 4 : 2;
4415 if (crtl->args.pretend_args_size)
4416 ra_size += 2;
4418 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx,
4419 GEN_INT (- ra_size)));
4423 msp430_incoming_return_addr_rtx (void)
4425 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
4428 /* If the path to the MSP430-GCC support files has been found by examining
4429 an environment variable (see msp430_check_env_var_for_devices in
4430 msp430-devices.c), or -mdevices-csv-loc=, register this path as an include
4431 directory so the user can #include msp430.h without needing to specify the
4432 path to the support files with -I. */
4433 void
4434 msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
4435 const char *iprefix ATTRIBUTE_UNUSED,
4436 int stdinc ATTRIBUTE_UNUSED)
4438 char *include_dir;
4439 if (msp430_devices_csv_loc)
4440 include_dir = xstrdup (msp430_devices_csv_loc);
4441 else if (msp430_check_env_var_for_devices (&include_dir))
4442 return;
4443 include_dir = msp430_dirname (include_dir);
4445 include_dir = update_path (include_dir, "");
4446 add_path (include_dir, INC_SYSTEM, false, false);
4449 /* Instruction generation stuff. */
4451 /* Generate a sequence of instructions to sign-extend an HI
4452 value into an SI value. Handles the tricky case where
4453 we are overwriting the destination.
4454 Return the number of bytes used by the emitted instructions.
4455 If RETURN_LENGTH is true then do not emit the assembly instruction
4456 sequence. */
4458 msp430x_extendhisi (rtx * operands, bool return_length)
4460 if (REGNO (operands[0]) == REGNO (operands[1]))
4462 /* Low word of dest == source word. */
4463 if (!return_length)
4464 output_asm_insn ("BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
4465 operands);
4466 return 8;
4468 else if (! msp430x)
4470 /* Note: This sequence is approximately the same length as invoking a
4471 helper function to perform the sign-extension, as in:
4473 MOV.W %1, %L0
4474 MOV.W %1, r12
4475 CALL __mspabi_srai_15
4476 MOV.W r12, %H0
4478 but this version does not involve any function calls or using argument
4479 registers, so it reduces register pressure. */
4480 if (!return_length)
4481 output_asm_insn ("MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
4482 operands);
4483 return 10;
4485 else if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
4487 /* High word of dest == source word. */
4488 if (!return_length)
4489 output_asm_insn ("MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0",
4490 operands);
4491 return 6;
4494 /* No overlap between dest and source. */
4495 if (!return_length)
4496 output_asm_insn ("MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0",
4497 operands);
4498 return 8;
4501 /* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */
4503 #undef TARGET_CAN_CHANGE_MODE_CLASS
4504 #define TARGET_CAN_CHANGE_MODE_CLASS msp430_can_change_mode_class
4506 static bool
4507 msp430_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t)
4509 if ((to == PSImode && from == SImode)
4510 || (to == SImode && from == PSImode)
4511 || (to == DImode && from == PSImode)
4512 || (to == PSImode && from == DImode))
4513 return false;
4514 return true;
4517 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
4518 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
4520 struct gcc_target targetm = TARGET_INITIALIZER;
4522 #include "gt-msp430.h"