1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2020 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)
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
25 #include "coretypes.h"
30 #include "stringpool.h"
32 #include "gimple-expr.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
46 #include "langhooks.h"
49 #include "msp430-devices.h"
53 /* This file should be included last. */
54 #include "target-def.h"
57 static void msp430_compute_frame_info (void);
58 static bool use_32bit_hwmult (void);
62 /* Run-time Target Specification. */
66 struct GTY(()) machine_function
68 /* If set, the rest of the fields have been computed. */
70 /* Which registers need to be saved in the pro/epilogue. */
71 int need_to_save[FIRST_PSEUDO_REGISTER];
73 /* These fields describe the frame layout... */
75 /* 2/4 bytes for saved PC */
79 int framesize_outgoing;
83 /* How much we adjust the stack when returning from an exception
88 /* This is our init_machine_status, as set in
89 msp430_option_override. */
90 static struct machine_function *
91 msp430_init_machine_status (void)
93 struct machine_function *m;
95 m = ggc_cleared_alloc<machine_function> ();
100 #undef TARGET_OPTION_OVERRIDE
101 #define TARGET_OPTION_OVERRIDE msp430_option_override
103 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
104 If a specific MCU has not been selected then return a generic symbol
108 msp430_mcu_name (void)
112 msp430_extract_mcu_data (target_mcu);
114 unsigned int start_upper;
115 unsigned int end_upper;
116 static char mcu_name[64];
118 /* The 'i' in the device name symbol for msp430i* devices must be lower
119 case, to match the expected symbol in msp430.h. */
120 if (strncmp (target_mcu, "msp430i", 7) == 0)
122 snprintf (mcu_name, sizeof (mcu_name) - 1, "__MSP430i%s__",
128 snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu);
131 end_upper = strlen (mcu_name) - 2;
132 for (i = start_upper; i < end_upper; i++)
133 mcu_name[i] = TOUPPER (mcu_name[i]);
137 return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
141 hwmult_name (unsigned int val)
145 case 0: return "none";
146 case 1: return "16-bit";
147 case 2: return "16-bit";
148 case 4: return "32-bit";
149 case 8: return "32-bit (5xx)";
150 default: gcc_unreachable ();
155 msp430_option_override (void)
157 /* The MSP430 architecture can safely dereference a NULL pointer. In fact,
158 there are memory mapped registers there. */
159 flag_delete_null_pointer_checks = 0;
161 init_machine_status = msp430_init_machine_status;
165 /* gcc/common/config/msp430-common.c will have
166 already canonicalised the string in target_cpu. */
167 if (strcasecmp (target_cpu, "msp430x") == 0)
169 else /* target_cpu == "msp430" - already handled by the front end. */
175 msp430_extract_mcu_data (target_mcu);
177 if (extracted_mcu_data.name != NULL)
179 bool xisa = extracted_mcu_data.revision >= 1;
183 if (target_cpu && msp430x != xisa)
184 warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
186 target_mcu, xisa ? "430X" : "430",
187 msp430x ? "430X" : "430");
189 if (extracted_mcu_data.hwmpy == 0
190 && msp430_hwmult_type != MSP430_HWMULT_AUTO
191 && msp430_hwmult_type != MSP430_HWMULT_NONE)
192 warning (0, "MCU %qs does not have hardware multiply "
193 "support, but %<-mhwmult%> is set to %s",
195 msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit"
196 : msp430_hwmult_type == MSP430_HWMULT_LARGE
197 ? "32-bit" : "f5series");
198 else if (msp430_hwmult_type == MSP430_HWMULT_SMALL
199 && extracted_mcu_data.hwmpy != 1
200 && extracted_mcu_data.hwmpy != 2)
201 warning (0, "MCU %qs supports %s hardware multiply, "
202 "but %<-mhwmult%> is set to 16-bit",
203 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
204 else if (msp430_hwmult_type == MSP430_HWMULT_LARGE
205 && extracted_mcu_data.hwmpy != 4)
206 warning (0, "MCU %qs supports %s hardware multiply, "
207 "but %<-mhwmult%> is set to 32-bit",
208 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
209 else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES
210 && extracted_mcu_data.hwmpy != 8)
211 warning (0, "MCU %qs supports %s hardware multiply, "
212 "but %<-mhwmult%> is set to f5series",
213 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
219 if (msp430_hwmult_type == MSP430_HWMULT_AUTO)
223 if (target_cpu == NULL)
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.",
232 "Unrecognized MCU name %qs, assuming that it "
233 "has no hardware multiply.\nUse the %<-mhwmult%> "
234 "option to set this explicitly.",
238 msp430_hwmult_type = MSP430_HWMULT_NONE;
240 else if (target_cpu == NULL)
244 "Unrecognized MCU name %qs, assuming that it just "
245 "supports the MSP430X ISA.\nUse the %<-mcpu%> option "
246 "to set the ISA explicitly.",
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 "
260 else if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_UPPER)
261 error ("%<-mcode-region=upper%> requires the large memory model "
264 if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_EITHER)
265 error ("%<-mdata-region=either%> requires the large memory model "
267 else if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_UPPER)
268 error ("%<-mdata-region=upper%> requires the large memory model "
271 if (flag_exceptions || flag_non_call_exceptions
272 || flag_unwind_tables || flag_asynchronous_unwind_tables)
273 flag_omit_frame_pointer = false;
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)
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");
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%>");
301 #undef TARGET_SCALAR_MODE_SUPPORTED_P
302 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
305 msp430_scalar_mode_supported_p (scalar_mode m)
307 if (m == PSImode && msp430x)
313 return default_scalar_mode_supported_p (m);
320 #undef TARGET_MS_BITFIELD_LAYOUT_P
321 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
324 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
333 #undef TARGET_HARD_REGNO_NREGS
334 #define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs
337 msp430_hard_regno_nregs (unsigned int, machine_mode mode)
339 if (mode == PSImode && msp430x)
341 if (mode == CPSImode && msp430x)
343 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
347 /* subreg_get_info correctly handles PSImode registers, so defining
348 HARD_REGNO_NREGS_HAS_PADDING and HARD_REGNO_NREGS_WITH_PADDING
351 #undef TARGET_HARD_REGNO_MODE_OK
352 #define TARGET_HARD_REGNO_MODE_OK msp430_hard_regno_mode_ok
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
365 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2)
367 if ((mode1 == PSImode || mode2 == SImode)
368 || (mode1 == SImode || mode2 == PSImode))
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
381 msp430_frame_pointer_required (void)
386 #undef TARGET_CAN_ELIMINATE
387 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
390 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
391 const int to_reg ATTRIBUTE_UNUSED)
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 ();
406 case STACK_POINTER_REGNUM:
407 rv += cfun->machine->framesize_outgoing;
408 rv += cfun->machine->framesize_locals;
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. */
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:
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)
451 case ADDR_SPACE_GENERIC:
453 case ADDR_SPACE_NEAR:
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
476 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
478 if (subset == superset)
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. */
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));
494 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
496 /* This is unpredictable, as we're truncating off usable address
500 return gen_rtx_CONST (HImode, op);
502 result = gen_reg_rtx (HImode);
503 emit_insn (gen_truncpsihi2 (result, op));
506 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
508 /* This always works. */
511 return gen_rtx_CONST (PSImode, op);
513 result = gen_reg_rtx (PSImode);
514 emit_insn (gen_zero_extendhipsi2 (result, op));
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",
535 "__adddf3", "__mspabi_addd",
536 "__subdf3", "__mspabi_subd",
537 "__muldf3", "__mspabi_mpyd",
538 "__divdf3", "__mspabi_divd",
543 /* TRUE if the function passed is a "speical" function. Special
544 functions pass two DImode parameters in registers. */
546 msp430_special_register_convention_p (const char *name)
550 for (i = 0; special_convention_function_names[i]; i++)
551 if (!strcmp (name, special_convention_function_names[i]))
557 #undef TARGET_FUNCTION_VALUE_REGNO_P
558 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
561 msp430_function_value_regno_p (unsigned int regno)
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. */
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)
596 memset (ca, 0, sizeof(*ca));
601 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
603 fname = XSTR (libname, 0);
607 if (fname && msp430_special_register_convention_p (fname))
611 /* Helper function for argument passing; this function is the common
612 code that determines where an argument will be passed. */
614 msp430_evaluate_arg (cumulative_args_t cap,
616 const_tree type ATTRIBUTE_UNUSED,
619 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
620 int nregs = GET_MODE_SIZE (mode);
632 nregs = (nregs + 1) / 2;
636 /* Function is passed two DImode operands, in R8:R11 and
646 for (i = 0; i < 4; i++)
647 if (!ca->reg_used[i])
650 ca->start_reg = CA_FIRST_REG + i;
655 for (i = 0; i < 3; i++)
656 if (!ca->reg_used[i] && !ca->reg_used[i + 1])
659 ca->start_reg = CA_FIRST_REG + i;
662 if (!ca->reg_used[3] && ca->can_split)
666 ca->start_reg = CA_FIRST_REG + 3;
679 ca->start_reg = CA_FIRST_REG;
686 #undef TARGET_PROMOTE_PROTOTYPES
687 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
690 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
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);
707 return gen_rtx_REG (arg.mode, ca->start_reg);
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;
728 #undef TARGET_PASS_BY_REFERENCE
729 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
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
746 msp430_function_arg_advance (cumulative_args_t cap,
747 const function_arg_info &arg)
749 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
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;
761 #undef TARGET_FUNCTION_ARG_BOUNDARY
762 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
765 msp430_function_arg_boundary (machine_mode mode, const_tree type)
768 && int_size_in_bytes (type) > 1)
770 if (GET_MODE_BITSIZE (mode) > 8)
775 #undef TARGET_RETURN_IN_MEMORY
776 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
779 msp430_return_in_memory (const_tree ret_type,
780 const_tree fntype ATTRIBUTE_UNUSED)
782 machine_mode mode = TYPE_MODE (ret_type);
785 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE)
786 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE))
789 if (GET_MODE_SIZE (mode) > 8)
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
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)
814 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
815 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
817 #include "gimplify.h"
820 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
823 tree addr, t, type_size, rounded_size, valist_tmp;
824 unsigned HOST_WIDE_INT align, boundary;
827 indirect = pass_va_arg_by_reference (type);
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
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. */
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),
862 build_int_cst (TREE_TYPE (valist),
864 gimplify_and_add (t, pre_p);
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);
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);
898 addr = build_va_arg_indirect_ref (addr);
900 addr = build_va_arg_indirect_ref (addr);
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
914 reg_ok_for_addr (rtx r, bool strict)
918 if (strict && rn >= FIRST_PSEUDO_REGISTER)
919 rn = reg_renumber[rn];
920 if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
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))
939 if (REG_P (XEXP (x, 0)))
941 if (GET_MODE (x) != GET_MODE (XEXP (x, 0)))
943 if (!reg_ok_for_addr (XEXP (x, 0), strict))
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. */
949 switch (GET_CODE (XEXP (x, 1)))
962 if (!reg_ok_for_addr (x, strict))
975 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
976 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
977 msp430_addr_space_legitimate_address_p
980 msp430_addr_space_legitimate_address_p (machine_mode mode,
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
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)
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);
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
1017 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
1023 #undef TARGET_LEGITIMATE_CONSTANT_P
1024 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1027 msp430_legitimate_constant (machine_mode mode, rtx x)
1029 return ! CONST_INT_P (x)
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
1034 || (INTVAL (x) < (1 << 20)
1035 && INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20));
1039 #undef TARGET_RTX_COSTS
1040 #define TARGET_RTX_COSTS msp430_rtx_costs
1042 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED,
1044 int outer_code ATTRIBUTE_UNUSED,
1045 int opno ATTRIBUTE_UNUSED,
1047 bool speed ATTRIBUTE_UNUSED)
1049 int code = GET_CODE (x);
1054 if (mode == SImode && outer_code == SET)
1056 *total = COSTS_N_INSNS (4);
1064 /* Function Entry and Exit */
1066 /* The MSP430 call frame looks like this:
1069 +--------------------+
1073 +--------------------+ <-- "arg pointer"
1075 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1077 +--------------------+
1078 | SR if this func has|
1079 | been called via an |
1081 +--------------------+ <-- SP before prologue, also AP
1083 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1085 +--------------------+ <-- "frame pointer"
1089 +--------------------+
1093 +--------------------+ <-- SP during function
1098 /* We use this to wrap all emitted insns in the prologue, so they get
1099 the "frame-related" (/f) flag set. */
1103 RTX_FRAME_RELATED_P (x) = 1;
1107 /* This is the one spot that decides if a register is to be saved and
1108 restored in the prologue/epilogue. */
1110 msp430_preserve_reg_p (int regno)
1112 /* PC, SP, SR, and the constant generator. */
1116 /* FIXME: add interrupt, EH, etc. */
1117 if (crtl->calls_eh_return)
1120 /* Shouldn't be more than the above, but just in case... */
1121 if (fixed_regs[regno])
1124 /* For interrupt functions we must save and restore the used regs that
1125 would normally be caller-saved (R11->R15). */
1126 if (msp430_is_interrupt_func () && regno >= 11 && regno <= 15)
1128 if (crtl->is_leaf && df_regs_ever_live_p (regno))
1129 /* If the interrupt func is a leaf then we only need to restore the
1130 caller-saved regs that are used. */
1132 else if (!crtl->is_leaf)
1133 /* If the interrupt function is not a leaf we must save all
1134 caller-saved regs in case the callee modifies them. */
1138 if (!call_used_or_fixed_reg_p (regno)
1139 && df_regs_ever_live_p (regno))
1145 /* Compute all the frame-related fields in our machine_function
1148 msp430_compute_frame_info (void)
1152 cfun->machine->computed = 1;
1153 cfun->machine->framesize_regs = 0;
1154 cfun->machine->framesize_locals = get_frame_size ();
1155 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
1157 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1158 if (msp430_preserve_reg_p (i))
1160 cfun->machine->need_to_save[i] = 1;
1161 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1164 cfun->machine->need_to_save[i] = 0;
1166 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1167 cfun->machine->framesize_locals ++;
1169 cfun->machine->framesize = (cfun->machine->framesize_regs
1170 + cfun->machine->framesize_locals
1171 + cfun->machine->framesize_outgoing);
1174 /* Attribute Handling. */
1176 const char * const ATTR_INTR = "interrupt";
1177 const char * const ATTR_WAKEUP = "wakeup";
1178 const char * const ATTR_NAKED = "naked";
1179 const char * const ATTR_REENT = "reentrant";
1180 const char * const ATTR_CRIT = "critical";
1181 const char * const ATTR_LOWER = "lower";
1182 const char * const ATTR_UPPER = "upper";
1183 const char * const ATTR_EITHER = "either";
1184 const char * const ATTR_NOINIT = "noinit";
1185 const char * const ATTR_PERSIST = "persistent";
1188 has_attr (const char * attr, tree decl)
1190 if (decl == NULL_TREE)
1192 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1196 is_interrupt_func (tree decl = current_function_decl)
1198 return has_attr (ATTR_INTR, decl);
1201 /* Returns true if the current function has the "interrupt" attribute. */
1204 msp430_is_interrupt_func (void)
1206 return is_interrupt_func (current_function_decl);
1210 is_wakeup_func (tree decl = current_function_decl)
1212 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1216 is_naked_func (tree decl = current_function_decl)
1218 return has_attr (ATTR_NAKED, decl);
1222 is_reentrant_func (tree decl = current_function_decl)
1224 return has_attr (ATTR_REENT, decl);
1228 is_critical_func (tree decl = current_function_decl)
1230 return has_attr (ATTR_CRIT, decl);
1234 has_section_name (const char * name, tree decl = current_function_decl)
1236 if (decl == NULL_TREE)
1238 return (DECL_SECTION_NAME (decl)
1239 && (strcmp (name, DECL_SECTION_NAME (decl)) == 0));
1242 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1243 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
1244 msp430_allocate_stack_slots_for_args
1247 msp430_allocate_stack_slots_for_args (void)
1249 /* Naked functions should not allocate stack slots for arguments. */
1250 return ! is_naked_func ();
1253 #undef TARGET_WARN_FUNC_RETURN
1254 #define TARGET_WARN_FUNC_RETURN msp430_warn_func_return
1257 msp430_warn_func_return (tree decl)
1259 /* Naked functions are implemented entirely in assembly, including the
1260 return sequence, so suppress warnings about this. */
1261 return !is_naked_func (decl);
1264 /* Verify MSP430 specific attributes. */
1265 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1268 msp430_attr (tree * node,
1271 int flags ATTRIBUTE_UNUSED,
1272 bool * no_add_attrs)
1274 gcc_assert (DECL_P (* node));
1276 /* Only the interrupt attribute takes an argument. */
1279 tree value = TREE_VALUE (args);
1281 switch (TREE_CODE (value))
1284 if ( strcmp (TREE_STRING_POINTER (value), "reset")
1285 && strcmp (TREE_STRING_POINTER (value), "nmi")
1286 && strcmp (TREE_STRING_POINTER (value), "watchdog"))
1287 /* Allow the attribute to be added - the linker script
1288 being used may still recognise this name. */
1289 warning (OPT_Wattributes,
1290 "unrecognized interrupt vector argument of %qE attribute",
1295 if (wi::gtu_p (wi::to_wide (value), 63))
1296 /* Allow the attribute to be added - the linker script
1297 being used may still recognise this value. */
1298 warning (OPT_Wattributes,
1299 "numeric argument of %qE attribute must be in range 0..63",
1304 warning (OPT_Wattributes,
1305 "argument of %qE attribute is not a string constant "
1307 *no_add_attrs = true;
1312 const char * message = NULL;
1314 if (TREE_CODE (* node) != FUNCTION_DECL)
1316 message = "%qE attribute only applies to functions";
1318 else if (TREE_NAME_EQ (name, ATTR_INTR))
1320 if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE
1321 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node))))
1322 message = "interrupt handlers must be void";
1325 /* Ensure interrupt handlers never get optimised out. */
1326 TREE_USED (* node) = 1;
1327 DECL_PRESERVE_P (* node) = 1;
1329 if (is_critical_func (* node))
1331 /* We always ignore the critical attribute when interrupt and
1332 critical are used together. */
1333 warning (OPT_Wattributes,
1334 "critical attribute has no effect on interrupt functions");
1335 DECL_ATTRIBUTES (*node) = remove_attribute (ATTR_CRIT,
1336 DECL_ATTRIBUTES (* node));
1339 else if (TREE_NAME_EQ (name, ATTR_CRIT))
1341 if (is_interrupt_func ( *node))
1342 message = "critical attribute has no effect on interrupt functions";
1347 warning (OPT_Wattributes, message, name);
1348 * no_add_attrs = true;
1355 msp430_section_attr (tree * node,
1358 int flags ATTRIBUTE_UNUSED,
1359 bool * no_add_attrs ATTRIBUTE_UNUSED)
1361 gcc_assert (DECL_P (* node));
1362 gcc_assert (args == NULL);
1364 const char * message = NULL;
1366 /* The "noinit" and "section" attributes are handled generically, so we
1367 cannot set up additional target-specific attribute exclusions using the
1368 existing mechanism. */
1369 if (has_attr (ATTR_NOINIT, *node))
1370 message = G_("ignoring attribute %qE because it conflicts with "
1371 "attribute %<noinit%>");
1372 else if (has_attr ("section", *node) && !TREE_NAME_EQ (name, "lower"))
1373 message = G_("ignoring attribute %qE because it conflicts with "
1374 "attribute %<section%>");
1375 /* It does not make sense to use upper/lower/either attributes without
1377 Without -mlarge, "lower" is the default and only region, so is redundant.
1378 Without -mlarge, "upper" will (and "either" might) place code/data in the
1379 upper region, which for data could result in relocation overflows, and for
1380 code could result in stack mismanagement and incorrect call/return
1382 else if (!TARGET_LARGE)
1383 message = G_("%qE attribute ignored. Large memory model (%<-mlarge%>) "
1388 warning (OPT_Wattributes, message, name);
1389 * no_add_attrs = true;
1396 msp430_persist_attr (tree *node,
1399 int flags ATTRIBUTE_UNUSED,
1400 bool * no_add_attrs ATTRIBUTE_UNUSED)
1402 const char * message = NULL;
1404 gcc_assert (DECL_P (* node));
1405 gcc_assert (args == NULL);
1406 gcc_assert (TREE_NAME_EQ (name, ATTR_PERSIST));
1408 /* Check for the section attribute separately from DECL_SECTION_NAME so
1409 we can provide a clearer warning. */
1410 if (has_attr ("section", *node))
1411 message = G_("ignoring attribute %qE because it conflicts with "
1412 "attribute %<section%>");
1413 /* Check that it's possible for the variable to have a section. */
1414 else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p)
1415 && (DECL_SECTION_NAME (*node)))
1416 message = G_("%qE attribute cannot be applied to variables with specific "
1418 else if (has_attr (ATTR_NOINIT, *node))
1419 message = G_("ignoring attribute %qE because it conflicts with "
1420 "attribute %<noinit%>");
1421 else if (TREE_CODE (*node) != VAR_DECL)
1422 message = G_("%qE attribute only applies to variables");
1423 else if (!TREE_STATIC (*node) && !TREE_PUBLIC (*node)
1424 && !DECL_EXTERNAL (*node))
1425 message = G_("%qE attribute has no effect on automatic variables");
1426 else if (DECL_COMMON (*node) || DECL_INITIAL (*node) == NULL)
1427 message = G_("variables marked with %qE attribute must be initialized");
1429 /* It's not clear if there is anything that can be set here to prevent the
1430 front end placing the variable before the back end can handle it, in a
1431 similar way to how DECL_COMMON is cleared for .noinit variables in
1432 handle_noinit_attribute (gcc/c-family/c-attribs.c).
1433 So just place the variable in the .persistent section now. */
1434 set_decl_section_name (* node, ".persistent");
1438 warning (OPT_Wattributes, message, name);
1439 * no_add_attrs = true;
1445 /* Helper to define attribute exclusions. */
1446 #define ATTR_EXCL(name, function, type, variable) \
1447 { name, function, type, variable }
1449 /* "reentrant", "critical" and "naked" functions must conflict because
1450 they all modify the prologue or epilogue of functions in mutually exclusive
1452 static const struct attribute_spec::exclusions attr_reent_exclusions[] =
1454 ATTR_EXCL (ATTR_NAKED, true, true, true),
1455 ATTR_EXCL (ATTR_CRIT, true, true, true),
1456 ATTR_EXCL (NULL, false, false, false)
1459 static const struct attribute_spec::exclusions attr_naked_exclusions[] =
1461 ATTR_EXCL (ATTR_REENT, true, true, true),
1462 ATTR_EXCL (ATTR_CRIT, true, true, true),
1463 ATTR_EXCL (NULL, false, false, false)
1466 static const struct attribute_spec::exclusions attr_crit_exclusions[] =
1468 ATTR_EXCL (ATTR_REENT, true, true, true),
1469 ATTR_EXCL (ATTR_NAKED, true, true, true),
1470 ATTR_EXCL (NULL, false, false, false)
1473 /* Attributes which put the given object in a specific section must conflict
1474 with one another. */
1475 static const struct attribute_spec::exclusions attr_lower_exclusions[] =
1477 ATTR_EXCL (ATTR_UPPER, true, true, true),
1478 ATTR_EXCL (ATTR_EITHER, true, true, true),
1479 ATTR_EXCL (ATTR_PERSIST, true, true, true),
1480 ATTR_EXCL (NULL, false, false, false)
1483 static const struct attribute_spec::exclusions attr_upper_exclusions[] =
1485 ATTR_EXCL (ATTR_LOWER, true, true, true),
1486 ATTR_EXCL (ATTR_EITHER, true, true, true),
1487 ATTR_EXCL (ATTR_PERSIST, true, true, true),
1488 ATTR_EXCL (NULL, false, false, false)
1491 static const struct attribute_spec::exclusions attr_either_exclusions[] =
1493 ATTR_EXCL (ATTR_LOWER, true, true, true),
1494 ATTR_EXCL (ATTR_UPPER, true, true, true),
1495 ATTR_EXCL (ATTR_PERSIST, true, true, true),
1496 ATTR_EXCL (NULL, false, false, false)
1499 static const struct attribute_spec::exclusions attr_persist_exclusions[] =
1501 ATTR_EXCL (ATTR_LOWER, true, true, true),
1502 ATTR_EXCL (ATTR_UPPER, true, true, true),
1503 ATTR_EXCL (ATTR_EITHER, true, true, true),
1504 ATTR_EXCL (NULL, false, false, false)
1507 #undef TARGET_ATTRIBUTE_TABLE
1508 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1510 /* Table of MSP430-specific attributes. */
1511 const struct attribute_spec msp430_attribute_table[] =
1513 /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
1514 affects_type_identity, handler, exclude } */
1515 { ATTR_INTR, 0, 1, true, false, false, false, msp430_attr, NULL },
1516 { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr,
1517 attr_naked_exclusions },
1518 { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr,
1519 attr_reent_exclusions },
1520 { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr,
1521 attr_crit_exclusions },
1522 { ATTR_WAKEUP, 0, 0, true, false, false, false, msp430_attr, NULL },
1524 { ATTR_LOWER, 0, 0, true, false, false, false, msp430_section_attr,
1525 attr_lower_exclusions },
1526 { ATTR_UPPER, 0, 0, true, false, false, false, msp430_section_attr,
1527 attr_upper_exclusions },
1528 { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr,
1529 attr_either_exclusions },
1531 { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_persist_attr,
1532 attr_persist_exclusions },
1534 { NULL, 0, 0, false, false, false, false, NULL, NULL }
1537 #undef TARGET_HANDLE_GENERIC_ATTRIBUTE
1538 #define TARGET_HANDLE_GENERIC_ATTRIBUTE msp430_handle_generic_attribute
1541 msp430_handle_generic_attribute (tree *node,
1543 tree args ATTRIBUTE_UNUSED,
1544 int flags ATTRIBUTE_UNUSED,
1548 const char *message = NULL;
1550 /* The front end has set up an exclusion between the "noinit" and "section"
1552 if (!(TREE_NAME_EQ (name, ATTR_NOINIT) || TREE_NAME_EQ (name, "section")))
1555 /* We allow the "lower" attribute to be used on variables with the "section"
1557 if (has_attr (ATTR_LOWER, *node) && !TREE_NAME_EQ (name, "section"))
1558 message = G_("ignoring attribute %qE because it conflicts with "
1559 "attribute %<lower%>");
1560 else if (has_attr (ATTR_UPPER, *node))
1561 message = G_("ignoring attribute %qE because it conflicts with "
1562 "attribute %<upper%>");
1563 else if (has_attr (ATTR_EITHER, *node))
1564 message = G_("ignoring attribute %qE because it conflicts with "
1565 "attribute %<either%>");
1566 else if (has_attr (ATTR_PERSIST, *node))
1567 message = G_("ignoring attribute %qE because it conflicts with "
1568 "attribute %<persistent%>");
1572 warning (OPT_Wattributes, message, name);
1573 *no_add_attrs = true;
1579 /* Given a non-automatic VAR_DECL which can possibly have a section, return
1580 true if the variable will definitely be placed in the lower memory
1581 region (below address 0x10000). */
1583 msp430_var_in_low_mem (tree decl)
1585 gcc_assert (VAR_P (decl));
1587 /* "noinit" variables are always placed in the lower memory region. */
1588 if (has_attr (ATTR_UPPER, decl)
1589 || has_attr (ATTR_EITHER, decl)
1590 || has_attr (ATTR_PERSIST, decl)
1591 /* Unless the variable is marked with the lower or noinit attribute, we
1592 cannot assume that it is in the lower region if it is marked with the
1593 section attribute or -mdata-region={upper,either,none} have been
1595 The noinit and section attributes conflict. */
1596 || (!has_attr (ATTR_LOWER, decl) && !has_attr (ATTR_NOINIT, decl)
1597 && (has_attr ("section", decl)
1598 || msp430_data_region == MSP430_REGION_UPPER
1599 || msp430_data_region == MSP430_REGION_EITHER
1600 || msp430_data_region == MSP430_REGION_ANY)))
1605 #undef TARGET_ENCODE_SECTION_INFO
1606 #define TARGET_ENCODE_SECTION_INFO msp430_encode_section_info
1608 /* Encode whether a SYMBOL_REF is definitely in the lower memory region. */
1610 msp430_encode_section_info (tree decl, rtx rtl, int first)
1613 default_encode_section_info (decl, rtl, first);
1615 /* Careful not to prod global register variables. */
1618 symbol = XEXP (rtl, 0);
1619 if (GET_CODE (symbol) != SYMBOL_REF)
1623 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1624 && msp430_var_in_low_mem (decl))
1625 SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOW_MEM;
1628 #undef TARGET_ASM_FUNCTION_PROLOGUE
1629 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1632 msp430_start_function (FILE *outfile)
1636 fprintf (outfile, "; start of function\n");
1638 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
1640 fprintf (outfile, "; attributes: ");
1641 if (is_naked_func ())
1642 fprintf (outfile, "naked ");
1643 if (msp430_is_interrupt_func ())
1644 fprintf (outfile, "interrupt ");
1645 if (is_reentrant_func ())
1646 fprintf (outfile, "reentrant ");
1647 if (is_critical_func ())
1648 fprintf (outfile, "critical ");
1649 if (is_wakeup_func ())
1650 fprintf (outfile, "wakeup ");
1651 fprintf (outfile, "\n");
1654 fprintf (outfile, "; framesize_regs: %d\n",
1655 cfun->machine->framesize_regs);
1656 fprintf (outfile, "; framesize_locals: %d\n",
1657 cfun->machine->framesize_locals);
1658 fprintf (outfile, "; framesize_outgoing: %d\n",
1659 cfun->machine->framesize_outgoing);
1660 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
1661 fprintf (outfile, "; elim ap -> fp %d\n",
1662 msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
1663 FRAME_POINTER_REGNUM));
1664 fprintf (outfile, "; elim fp -> sp %d\n",
1665 msp430_initial_elimination_offset (FRAME_POINTER_REGNUM,
1666 STACK_POINTER_REGNUM));
1669 fprintf (outfile, "; saved regs:");
1670 for (r = 0; r < ARG_POINTER_REGNUM; r++)
1671 if (cfun->machine->need_to_save[r])
1673 fprintf (outfile, " %s", reg_names[r]);
1677 fprintf (outfile, "(none)");
1678 fprintf (outfile, "\n");
1681 /* Common code to change the stack pointer. */
1683 increment_stack (HOST_WIDE_INT amount)
1686 rtx sp = stack_pointer_rtx;
1693 inc = GEN_INT (- amount);
1695 F (emit_insn (gen_subpsi3 (sp, sp, inc)));
1697 F (emit_insn (gen_subhi3 (sp, sp, inc)));
1701 inc = GEN_INT (amount);
1703 emit_insn (gen_addpsi3 (sp, sp, inc));
1705 emit_insn (gen_addhi3 (sp, sp, inc));
1710 msp430_start_function (FILE *file, const char *name, tree decl)
1714 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1715 if (int_attr != NULL_TREE)
1717 tree intr_vector = TREE_VALUE (int_attr);
1719 if (intr_vector != NULL_TREE)
1723 /* Interrupt vector sections should be unique, but use of weak
1724 functions implies multiple definitions. */
1725 if (DECL_WEAK (decl))
1727 error ("argument to interrupt attribute is unsupported for weak "
1731 intr_vector = TREE_VALUE (intr_vector);
1733 /* The interrupt attribute has a vector value. Turn this into a
1734 section name, switch to that section and put the address of
1735 the current function into that vector slot. Note msp430_attr()
1736 has already verified the vector name for us. */
1737 if (TREE_CODE (intr_vector) == STRING_CST)
1738 sprintf (buf, "__interrupt_vector_%.80s",
1739 TREE_STRING_POINTER (intr_vector));
1740 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1741 sprintf (buf, "__interrupt_vector_%u",
1742 (unsigned int) TREE_INT_CST_LOW (intr_vector));
1744 switch_to_section (get_section (buf, SECTION_CODE, decl));
1745 fputs ("\t.word\t", file);
1746 assemble_name (file, name);
1752 switch_to_section (function_section (decl));
1753 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
1754 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1757 static const char * const lower_prefix = ".lower";
1758 static const char * const upper_prefix = ".upper";
1759 static const char * const either_prefix = ".either";
1761 /* Generate a prefix for a section name, based upon
1762 the region into which the object should be placed. */
1765 gen_prefix (tree decl)
1767 if (DECL_ONE_ONLY (decl))
1770 /* If the user has specified a particular section then do not use any
1772 if (has_attr ("section", decl))
1775 /* If the function has been put in the .lowtext section (because it is an
1776 interrupt handler, and the large memory model is used), then do not add
1778 if (has_section_name (".lowtext", decl))
1781 /* Memory regions require the large memory model. */
1785 /* Note that we always apply the lower prefix when the attribute has been
1786 used. But we only apply the lower prefix when the lower region has been
1787 specified by a command line option if -muse-lower-region-prefix has also
1789 if (has_attr (ATTR_LOWER, decl))
1790 return lower_prefix;
1792 if (has_attr (ATTR_UPPER, decl))
1793 return upper_prefix;
1795 if (has_attr (ATTR_EITHER, decl))
1796 return either_prefix;
1798 if (TREE_CODE (decl) == FUNCTION_DECL)
1800 if ((msp430_code_region == MSP430_REGION_LOWER)
1801 && TARGET_USE_LOWER_REGION_PREFIX)
1802 return lower_prefix;
1804 if (msp430_code_region == MSP430_REGION_UPPER)
1805 return upper_prefix;
1807 if (msp430_code_region == MSP430_REGION_EITHER)
1808 return either_prefix;
1812 if ((msp430_data_region == MSP430_REGION_LOWER)
1813 && TARGET_USE_LOWER_REGION_PREFIX)
1814 return lower_prefix;
1816 if (msp430_data_region == MSP430_REGION_UPPER)
1817 return upper_prefix;
1819 if (msp430_data_region == MSP430_REGION_EITHER)
1820 return either_prefix;
1826 static section * persist_section;
1828 #undef TARGET_ASM_INIT_SECTIONS
1829 #define TARGET_ASM_INIT_SECTIONS msp430_init_sections
1832 msp430_init_sections (void)
1834 persist_section = get_unnamed_section (0, output_section_asm_op,
1835 ".section .persistent,\"aw\"");
1838 #undef TARGET_ASM_SELECT_SECTION
1839 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1842 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
1845 const char *sec_name;
1846 const char *base_sec_name;
1848 gcc_assert (decl != NULL_TREE);
1850 if (TREE_CODE (decl) == STRING_CST
1851 || TREE_CODE (decl) == CONSTRUCTOR
1852 || TREE_CODE (decl) == INTEGER_CST
1853 || TREE_CODE (decl) == VECTOR_CST
1854 || TREE_CODE (decl) == COMPLEX_CST)
1855 return default_select_section (decl, reloc, align);
1857 /* In large mode we must make sure that interrupt handlers are put into
1858 low memory as the vector table only accepts 16-bit addresses. */
1859 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
1860 && is_interrupt_func (decl))
1861 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
1863 if (has_attr (ATTR_PERSIST, decl))
1864 return persist_section;
1866 /* ATTR_NOINIT is handled generically. */
1867 if (has_attr (ATTR_NOINIT, decl))
1868 return default_elf_select_section (decl, reloc, align);
1870 prefix = gen_prefix (decl);
1872 switch (categorize_decl_for_section (decl, reloc))
1876 return text_section;
1877 base_sec_name = ".text";
1881 return data_section;
1882 base_sec_name = ".data";
1887 base_sec_name = ".bss";
1891 return readonly_data_section;
1892 base_sec_name = ".rodata";
1895 /* Enable merging of constant data by the GNU linker using
1896 default_elf_select_section and therefore enabling creation of
1897 sections with the SHF_MERGE flag. */
1898 case SECCAT_RODATA_MERGE_STR:
1899 case SECCAT_RODATA_MERGE_STR_INIT:
1900 case SECCAT_RODATA_MERGE_CONST:
1901 return default_elf_select_section (decl, reloc, align);
1903 /* The sections listed below are not supported for MSP430.
1904 They should not be generated, but in case they are, we use
1905 default_select_section so they get placed in sections
1906 the msp430 assembler and linker understand. */
1907 /* "small data" sections are not supported. */
1908 case SECCAT_SRODATA:
1911 /* Thread-local storage (TLS) is not supported. */
1914 /* Sections used by a dynamic linker are not supported. */
1915 case SECCAT_DATA_REL:
1916 case SECCAT_DATA_REL_LOCAL:
1917 case SECCAT_DATA_REL_RO:
1918 case SECCAT_DATA_REL_RO_LOCAL:
1919 return default_select_section (decl, reloc, align);
1925 sec_name = ACONCAT ((prefix, base_sec_name, DECL_SECTION_NAME (decl), NULL));
1927 return get_named_section (decl, sec_name, 0);
1930 #undef TARGET_ASM_FUNCTION_SECTION
1931 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1934 msp430_function_section (tree decl, enum node_frequency freq, bool startup,
1939 gcc_assert (DECL_SECTION_NAME (decl) != NULL);
1940 name = DECL_SECTION_NAME (decl);
1942 const char * prefix = gen_prefix (decl);
1944 || strncmp (name, prefix, strlen (prefix)) == 0)
1945 return default_function_section (decl, freq, startup, exit);
1947 name = ACONCAT ((prefix, name, NULL));
1948 return get_named_section (decl, name, 0);
1951 #undef TARGET_SECTION_TYPE_FLAGS
1952 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1955 msp430_section_type_flags (tree decl, const char * name, int reloc)
1957 if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0)
1958 name += strlen (lower_prefix);
1959 else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0)
1960 name += strlen (upper_prefix);
1961 else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
1962 name += strlen (either_prefix);
1963 else if (strcmp (name, ".persistent") == 0)
1964 return SECTION_WRITE | SECTION_NOTYPE;
1966 return default_section_type_flags (decl, name, reloc);
1969 #undef TARGET_ASM_UNIQUE_SECTION
1970 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1973 msp430_unique_section (tree decl, int reloc)
1975 gcc_assert (decl != NULL_TREE);
1977 /* In large mode we must make sure that interrupt handlers are put into
1978 low memory as the vector table only accepts 16-bit addresses. */
1979 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
1980 && is_interrupt_func (decl))
1982 set_decl_section_name (decl, ".lowtext");
1986 default_unique_section (decl, reloc);
1988 const char * prefix;
1990 if ( TREE_CODE (decl) == STRING_CST
1991 || TREE_CODE (decl) == CONSTRUCTOR
1992 || TREE_CODE (decl) == INTEGER_CST
1993 || TREE_CODE (decl) == VECTOR_CST
1994 || TREE_CODE (decl) == COMPLEX_CST
1995 || (prefix = gen_prefix (decl)) == NULL)
1998 const char * dec_name = DECL_SECTION_NAME (decl);
1999 char * name = ACONCAT ((prefix, dec_name, NULL));
2001 set_decl_section_name (decl, name);
2004 /* Emit a declaration of a common symbol.
2005 If a data region is in use then put the symbol into the
2006 equivalent .bss section instead.
2007 If LOCAL is 1, then DECL is for a local common variable. */
2009 msp430_output_aligned_decl_common (FILE * stream,
2012 unsigned HOST_WIDE_INT size,
2016 /* Only emit a common symbol if the variable does not have a specific section
2018 if ((msp430_data_region == MSP430_REGION_ANY
2019 || ((msp430_data_region == MSP430_REGION_LOWER)
2020 && !TARGET_USE_LOWER_REGION_PREFIX))
2021 && !(decl != NULL_TREE && DECL_SECTION_NAME (decl))
2022 && !has_attr (ATTR_EITHER, decl)
2023 && !has_attr (ATTR_LOWER, decl)
2024 && !has_attr (ATTR_UPPER, decl)
2025 && !has_attr (ATTR_PERSIST, decl)
2026 && !has_attr (ATTR_NOINIT, decl))
2030 fprintf (stream, LOCAL_ASM_OP);
2031 assemble_name (stream, name);
2032 fprintf (stream, "\n");
2034 fprintf (stream, COMMON_ASM_OP);
2035 assemble_name (stream, name);
2036 fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
2037 size, align / BITS_PER_UNIT);
2044 sec = msp430_select_section (decl, 0, align);
2046 switch (msp430_data_region)
2048 case MSP430_REGION_UPPER:
2049 sec = get_named_section (NULL, ".upper.bss", 0);
2051 case MSP430_REGION_LOWER:
2052 sec = get_named_section (NULL, ".lower.bss", 0);
2054 case MSP430_REGION_EITHER:
2055 sec = get_named_section (NULL, ".either.bss", 0);
2060 gcc_assert (sec != NULL);
2062 switch_to_section (sec);
2063 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
2066 targetm.asm_out.globalize_label (stream, name);
2067 ASM_WEAKEN_LABEL (stream, name);
2069 ASM_OUTPUT_LABEL (stream, name);
2070 ASM_OUTPUT_SKIP (stream, size ? size : 1);
2074 #undef TARGET_ASM_FILE_END
2075 #define TARGET_ASM_FILE_END msp430_file_end
2077 /* Emit MSPABI and GNU object attributes.
2078 Tags and values for MSPABI attributes are:
2079 OFBA_MSPABI_Tag_ISA 4
2082 OFBA_MSPABI_Tag_Code_Model 6
2085 OFBA_MSPABI_Tag_Data_Model 8
2088 Restricted 3 (Unused by GNU)
2089 OFBA_MSPABI_Tag_enum_size 10 (Unused by GNU)
2090 Note that Code_Model and Data_Model are always equal for GNU.
2091 We define a new .gnu_attribute to keep track of the data region used.
2092 Tag_GNU_MSP430_Data_Region 4
2095 See binutils-gdb/include/elf/msp430.h for the full details. */
2097 msp430_file_end (void)
2099 #ifdef HAVE_AS_GNU_ATTRIBUTE
2100 /* Enum for tag names. */
2103 OFBA_MSPABI_Tag_ISA = 4,
2104 OFBA_MSPABI_Tag_Code_Model = 6,
2105 OFBA_MSPABI_Tag_Data_Model = 8,
2106 Tag_GNU_MSP430_Data_Region = 4
2108 /* Enum for tag values. */
2111 OFBA_MSPABI_Val_ISA_MSP430 = 1,
2112 OFBA_MSPABI_Val_ISA_MSP430X = 2,
2113 OFBA_MSPABI_Val_Model_Small = 1,
2114 OFBA_MSPABI_Val_Model_Large = 2,
2115 Tag_GNU_MSP430_Data_Region_Lower = 1,
2116 Tag_GNU_MSP430_Data_Region_Any = 2
2118 /* .mspabi_attribute is a GNU assembler directive only. The assembler will
2119 construct a .MSP430.attributes section based on the options it is invoked
2120 with. The values it reads from these directives are used for validating
2122 const char *msp430_attr = ".mspabi_attribute";
2123 const char *gnu_attr = ".gnu_attribute";
2125 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_ISA. */
2126 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr, OFBA_MSPABI_Tag_ISA,
2127 msp430x ? OFBA_MSPABI_Val_ISA_MSP430X : OFBA_MSPABI_Val_ISA_MSP430);
2128 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Code_Model. */
2129 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2130 OFBA_MSPABI_Tag_Code_Model,
2131 TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2132 : OFBA_MSPABI_Val_Model_Small);
2133 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Data_Model. */
2134 fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2135 OFBA_MSPABI_Tag_Data_Model,
2136 TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2137 : OFBA_MSPABI_Val_Model_Small);
2138 #ifdef HAVE_AS_MSPABI_ATTRIBUTE
2139 /* Emit .gnu_attribute directive for Tag_GNU_MSP430_Data_Region. */
2140 fprintf (asm_out_file, "\t%s %d, %d\n", gnu_attr, Tag_GNU_MSP430_Data_Region,
2141 msp430_data_region == MSP430_REGION_LOWER
2142 ? Tag_GNU_MSP430_Data_Region_Lower
2143 : Tag_GNU_MSP430_Data_Region_Any);
2150 MSP430_BUILTIN_BIC_SR,
2151 MSP430_BUILTIN_BIS_SR,
2152 MSP430_BUILTIN_DELAY_CYCLES,
2156 static GTY(()) tree msp430_builtins[(int) MSP430_BUILTIN_max];
2159 msp430_init_builtins (void)
2161 tree void_ftype_int = build_function_type_list (void_type_node,
2162 integer_type_node, NULL);
2163 tree void_ftype_longlong
2164 = build_function_type_list (void_type_node, long_long_integer_type_node,
2167 msp430_builtins[MSP430_BUILTIN_BIC_SR] =
2168 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
2169 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
2171 msp430_builtins[MSP430_BUILTIN_BIS_SR] =
2172 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
2173 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
2175 msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
2176 add_builtin_function ( "__delay_cycles", void_ftype_longlong,
2177 MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL,
2182 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
2186 case MSP430_BUILTIN_BIC_SR:
2187 case MSP430_BUILTIN_BIS_SR:
2188 case MSP430_BUILTIN_DELAY_CYCLES:
2189 return msp430_builtins[code];
2191 return error_mark_node;
2195 /* These constants are really register reads, which are faster than
2196 regular constants. */
2198 cg_magic_constant (HOST_WIDE_INT c)
2216 msp430_expand_delay_cycles (rtx arg)
2218 HOST_WIDE_INT i, c, n;
2219 /* extra cycles for MSP430X instructions */
2220 #define CYCX(M,X) (msp430x ? (X) : (M))
2222 if (GET_CODE (arg) != CONST_INT)
2224 error ("__delay_cycles() only takes constant arguments");
2230 if (HOST_BITS_PER_WIDE_INT > 32)
2234 error ("__delay_cycles only takes non-negative cycle counts");
2239 emit_insn (gen_delay_cycles_start (arg));
2241 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
2242 if (c > 3 * 0xffff + CYCX (7, 10))
2245 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long
2246 (x<=0xffff) loop. */
2247 if (c >= 0x10000 * 7 + CYCX (14, 16))
2250 c -= CYCX (14, 16) + 7 * 0x10000;
2253 if ((unsigned long long) i > 0xffffffffULL)
2255 error ("__delay_cycles is limited to 32-bit loop counts");
2261 i = (c - CYCX (14, 16)) / 7;
2262 c -= CYCX (14, 16) + i * 7;
2265 if (cg_magic_constant (i & 0xffff))
2267 if (cg_magic_constant ((i >> 16) & 0xffff))
2271 emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c)));
2273 emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
2276 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is
2281 i = (c - CYCX (7, 10)) / 3;
2282 c -= CYCX (7, 10) + i * 3;
2284 if (cg_magic_constant (i))
2288 emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c)));
2290 emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c)));
2295 emit_insn (gen_delay_cycles_2 ());
2301 emit_insn (gen_delay_cycles_1 ());
2305 emit_insn (gen_delay_cycles_end (arg));
2311 msp430_expand_builtin (tree exp,
2312 rtx target ATTRIBUTE_UNUSED,
2313 rtx subtarget ATTRIBUTE_UNUSED,
2314 machine_mode mode ATTRIBUTE_UNUSED,
2315 int ignore ATTRIBUTE_UNUSED)
2317 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2318 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
2319 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2321 if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
2322 return msp430_expand_delay_cycles (arg1);
2324 if (! msp430_is_interrupt_func ())
2326 error ("MSP430 builtin functions only work inside interrupt handlers");
2330 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
2331 arg1 = force_reg (mode, arg1);
2335 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break;
2336 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break;
2338 internal_error ("bad builtin code");
2344 #undef TARGET_INIT_BUILTINS
2345 #define TARGET_INIT_BUILTINS msp430_init_builtins
2347 #undef TARGET_EXPAND_BUILTIN
2348 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
2350 #undef TARGET_BUILTIN_DECL
2351 #define TARGET_BUILTIN_DECL msp430_builtin_decl
2354 msp430_expand_prologue (void)
2358 /* Always use stack_pointer_rtx instead of calling
2359 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
2360 that there is a single rtx representing the stack pointer,
2361 namely stack_pointer_rtx, and uses == to recognize it. */
2362 rtx sp = stack_pointer_rtx;
2365 if (is_naked_func ())
2367 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2368 examines the output of the gen_prologue() function. */
2369 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2373 emit_insn (gen_prologue_start_marker ());
2375 if (is_critical_func ())
2377 emit_insn (gen_push_intr_state ());
2378 emit_insn (gen_disable_interrupts ());
2380 else if (is_reentrant_func ())
2381 emit_insn (gen_disable_interrupts ());
2383 if (!cfun->machine->computed)
2384 msp430_compute_frame_info ();
2386 if (flag_stack_usage_info)
2387 current_function_static_stack_size = cfun->machine->framesize;
2389 if (crtl->args.pretend_args_size)
2393 gcc_assert (crtl->args.pretend_args_size == 2);
2395 p = emit_insn (gen_grow_and_swap ());
2397 /* Document the stack decrement... */
2398 note = F (gen_rtx_SET (stack_pointer_rtx,
2399 gen_rtx_MINUS (Pmode,
2400 stack_pointer_rtx, GEN_INT (2))));
2401 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2403 /* ...and the establishment of a new location for the return address. */
2404 note = F (gen_rtx_SET (gen_rtx_MEM (Pmode,
2405 gen_rtx_PLUS (Pmode,
2409 add_reg_note (p, REG_CFA_OFFSET, note);
2413 for (i = 15; i >= 4; i--)
2414 if (cfun->machine->need_to_save[i])
2419 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
2425 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two
2427 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
2430 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2432 XVECEXP (note, 0, 0)
2433 = F (gen_rtx_SET (stack_pointer_rtx,
2434 gen_rtx_PLUS (Pmode,
2436 GEN_INT (count * (TARGET_LARGE
2439 /* *sp-- = R[i-j] */
2443 for (j = 0; j < count; j ++)
2446 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2449 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2451 addr = stack_pointer_rtx;
2453 XVECEXP (note, 0, j + 1) =
2454 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2455 gen_rtx_REG (Pmode, i - j)));
2458 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2462 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2465 if (frame_pointer_needed)
2466 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2468 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2470 increment_stack (- fs);
2472 emit_insn (gen_prologue_end_marker ());
2476 msp430_expand_epilogue (int is_eh)
2482 if (is_naked_func ())
2484 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2485 examines the output of the gen_epilogue() function. */
2486 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2490 if (cfun->machine->need_to_save[10])
2492 /* Check for a helper function. */
2493 helper_n = 7; /* For when the loop below never sees a match. */
2494 for (i = 9; i >= 4; i--)
2495 if (!cfun->machine->need_to_save[i])
2499 if (cfun->machine->need_to_save[i])
2508 emit_insn (gen_epilogue_start_marker ());
2510 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)),
2512 emit_insn (gen_msp430_refsym_need_exit ());
2514 if (is_wakeup_func ())
2515 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2516 status register current residing on the stack. When this function
2517 executes its RETI instruction the SR will be updated with this saved
2518 value, thus ensuring that the processor is woken up from any low power
2519 state in which it may be residing. */
2520 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2522 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2524 increment_stack (fs);
2528 /* We need to add the right "SP" register save just after the
2529 regular ones, so that when we pop it off we're in the EH
2530 return frame, not this one. This overwrites our own return
2531 address, but we're not going to be returning anyway. */
2532 rtx r12 = gen_rtx_REG (Pmode, 12);
2533 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
2535 /* R12 will hold the new SP. */
2536 i = cfun->machine->framesize_regs;
2537 emit_move_insn (r12, stack_pointer_rtx);
2538 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
2539 emit_insn (addPmode (r12, r12, GEN_INT (i)));
2540 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode,
2545 for (i = 4; i <= 15; i++)
2546 if (cfun->machine->need_to_save[i])
2550 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
2556 /* Note: With TARGET_LARGE we still use
2557 POPM as POPX.A is two bytes bigger. */
2558 emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
2562 else if (i == 11 - helper_n
2563 && ! msp430_is_interrupt_func ()
2564 && ! is_reentrant_func ()
2565 && ! is_critical_func ()
2566 && crtl->args.pretend_args_size == 0
2567 /* Calling the helper takes as many bytes as the POP;RET
2572 emit_jump_insn (gen_epilogue_helper (GEN_INT (helper_n)));
2576 emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
2581 /* Also pop SP, which puts us into the EH return frame. Except
2582 that you can't "pop" sp, you have to just load it off the
2584 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode,
2585 stack_pointer_rtx));
2588 if (crtl->args.pretend_args_size)
2589 emit_insn (gen_swap_and_shrink ());
2591 if (is_critical_func ())
2592 emit_insn (gen_pop_intr_state ());
2593 else if (is_reentrant_func ())
2594 emit_insn (gen_enable_interrupts ());
2596 emit_jump_insn (gen_msp430_return ());
2599 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2600 m32c_emit_eh_epilogue. */
2602 msp430_eh_return_stackadj_rtx (void)
2604 if (!cfun->machine->eh_stack_adjust)
2608 sa = gen_rtx_REG (Pmode, 15);
2609 cfun->machine->eh_stack_adjust = sa;
2611 return cfun->machine->eh_stack_adjust;
2614 /* This function is called before reload, to "fix" the stack in
2615 preparation for an EH return. */
2617 msp430_expand_eh_return (rtx eh_handler)
2619 /* These are all Pmode */
2620 rtx ap, sa, ra, tmp;
2622 ap = arg_pointer_rtx;
2623 sa = msp430_eh_return_stackadj_rtx ();
2627 tmp = gen_rtx_PLUS (Pmode, ap, sa);
2628 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
2629 tmp = gen_rtx_MEM (Pmode, tmp);
2630 emit_move_insn (tmp, ra);
2633 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
2634 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2636 msp430_init_dwarf_reg_sizes_extra (tree address)
2639 rtx addr = expand_normal (address);
2640 rtx mem = gen_rtx_MEM (BLKmode, addr);
2642 /* This needs to match msp430_unwind_word_mode (above). */
2646 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2648 unsigned int dnum = DWARF_FRAME_REGNUM (i);
2649 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
2651 if (rnum < DWARF_FRAME_REGISTERS)
2653 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
2655 emit_move_insn (adjust_address (mem, QImode, offset),
2656 gen_int_mode (4, QImode));
2661 /* The MSP430 ABI defines a number of helper functions that should be
2662 used for, for example, 32-bit shifts. This function is called to
2663 emit such a function, using the table above to optimize some
2666 msp430_expand_helper (rtx *operands, const char *helper_name,
2667 bool const_variants)
2669 rtx c, fusage, fsym;
2670 char *helper_const = NULL;
2674 machine_mode arg0mode = GET_MODE (operands[0]);
2675 machine_mode arg1mode = GET_MODE (operands[1]);
2676 machine_mode arg2mode = GET_MODE (operands[2]);
2677 int expand_mpy = strncmp (helper_name, "__mspabi_mpy",
2678 sizeof ("__mspabi_mpy") - 1) == 0;
2679 /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a
2681 gcc_assert (!(expand_mpy && const_variants));
2683 if (arg1mode != VOIDmode && arg2mode != VOIDmode)
2684 /* Modes of arguments must be equal if not constants. */
2685 gcc_assert (arg1mode == arg2mode);
2687 if (arg1mode == VOIDmode)
2688 arg1mode = arg0mode;
2689 if (arg2mode == VOIDmode)
2690 arg2mode = arg0mode;
2692 if (arg1mode == SImode)
2697 else if (arg1mode == DImode)
2704 /* Use the "const_variant" of a shift library function if requested.
2705 These are faster, but have larger code size. */
2707 && CONST_INT_P (operands[2])
2708 && INTVAL (operands[2]) >= 1
2709 && INTVAL (operands[2]) <= 15)
2711 /* Note that the INTVAL is limited in value and length by the conditional
2713 int len = strlen (helper_name) + 4;
2714 helper_const = (char *) xmalloc (len);
2715 snprintf (helper_const, len, "%s_%d", helper_name,
2716 (int) INTVAL (operands[2]));
2719 /* Setup the arguments to the helper function. */
2720 emit_move_insn (gen_rtx_REG (arg1mode, arg1),
2723 emit_move_insn (gen_rtx_REG (arg2mode, arg2),
2728 if (msp430_use_f5_series_hwmult ())
2729 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2731 else if (use_32bit_hwmult ())
2733 /* When the arguments are 16-bits, the 16-bit hardware multiplier is
2735 if (arg1mode == HImode)
2736 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2739 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2742 /* 16-bit hardware multiply. */
2743 else if (msp430_has_hwmult ())
2744 fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2747 fsym = gen_rtx_SYMBOL_REF (VOIDmode, helper_name);
2750 fsym = gen_rtx_SYMBOL_REF (VOIDmode,
2751 helper_const ? helper_const : helper_name);
2753 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), fsym, GEN_INT (0));
2755 c = emit_call_insn (c);
2756 RTL_CONST_CALL_P (c) = 1;
2758 /* Add register usage information for the arguments to the call. */
2760 use_regs (&fusage, arg1, arg1sz);
2763 /* If we are expanding a shift, we only need to use the low register
2764 for the shift amount. */
2766 use_regs (&fusage, arg2, 1);
2768 use_regs (&fusage, arg2, arg1sz);
2770 add_function_usage_to (c, fusage);
2772 emit_move_insn (operands[0],
2773 /* Return value will always start in R12. */
2774 gen_rtx_REG (arg0mode, 12));
2777 /* Return TRUE if the helper function should be used and FALSE if the shifts
2778 insns should be emitted inline. */
2780 use_helper_for_const_shift (enum rtx_code code, machine_mode mode,
2783 const int default_inline_shift = 4;
2784 /* We initialize the option to 65 so we know if the user set it or not. */
2785 int user_set_max_inline = (msp430_max_inline_shift == 65 ? 0 : 1);
2786 int max_inline = (user_set_max_inline ? msp430_max_inline_shift
2787 : default_inline_shift);
2788 /* 32-bit shifts are roughly twice as costly as 16-bit shifts so we adjust
2789 the heuristic accordingly. */
2790 int max_inline_32 = max_inline / 2;
2792 /* Don't use helpers for these modes on 430X, when optimizing for speed, or
2793 when emitting a small number of insns. */
2794 if ((mode == E_QImode || mode == E_HImode || mode == E_PSImode)
2796 /* If the user set max_inline then we always obey that number.
2797 Otherwise we always emit the shifts inline at -O2 and above. */
2798 || amt <= max_inline
2799 || (!user_set_max_inline
2800 && (optimize >= 2 && !optimize_size))))
2803 /* 430 and 430X codegen for SImode shifts is the same.
2804 Set a hard limit of 15 for the number of shifts that will be emitted
2805 inline by default, even at -O2 and above, to prevent code size
2807 if (mode == E_SImode
2808 && (amt <= max_inline_32
2809 || (!user_set_max_inline
2810 && (optimize >= 2 && !optimize_size)
2817 /* For shift operations which will use an mspabi helper function, setup the
2818 call to msp430_expand helper. Return 1 to indicate we have finished with
2819 this insn and invoke "DONE".
2820 Otherwise return 0 to indicate the insn should fallthrough.
2823 msp430_expand_shift (enum rtx_code code, machine_mode mode, rtx *operands)
2825 /* Always use the helper function when the shift amount is not a
2827 if (!CONST_INT_P (operands[2])
2829 || use_helper_for_const_shift (code, mode, INTVAL (operands[2])))
2831 const char *helper_name = NULL;
2832 /* The const variants of mspabi shifts have significantly larger code
2833 size than the generic version, so use the generic version if
2834 optimizing for size. */
2835 bool const_variant = !optimize_size;
2839 helper_name = (code == ASHIFT ? "__mspabi_slli" :
2840 (code == ASHIFTRT ? "__mspabi_srai" :
2841 (code == LSHIFTRT ? "__mspabi_srli" :
2845 helper_name = (code == ASHIFT ? "__gnu_mspabi_sllp" :
2846 (code == ASHIFTRT ? "__gnu_mspabi_srap" :
2847 (code == LSHIFTRT ? "__gnu_mspabi_srlp" :
2849 /* No const variant for PSImode shifts FIXME. */
2850 const_variant = false;
2853 helper_name = (code == ASHIFT ? "__mspabi_slll" :
2854 (code == ASHIFTRT ? "__mspabi_sral" :
2855 (code == LSHIFTRT ? "__mspabi_srll" :
2859 helper_name = (code == ASHIFT ? "__mspabi_sllll" :
2860 (code == ASHIFTRT ? "__mspabi_srall" :
2861 (code == LSHIFTRT ? "__mspabi_srlll" :
2863 /* No const variant for DImode shifts. */
2864 const_variant = false;
2870 gcc_assert (helper_name);
2871 msp430_expand_helper (operands, helper_name, const_variant);
2874 /* When returning 0, there must be an insn to match the RTL pattern
2875 otherwise there will be an unrecognizeable insn. */
2879 /* Helper function to emit a sequence of shift instructions. The amount of
2880 shift instructions to emit is in OPERANDS[2].
2881 For 430 we output copies of identical inline shifts for all modes.
2882 For 430X it is inneficient to do so for any modes except SI and DI, since we
2883 can make use of R*M insns or RPT with 430X insns, so this function is only
2884 used for SImode in that case. */
2886 msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode,
2891 int max_shift = GET_MODE_BITSIZE (mode) - 1;
2892 gcc_assert (CONST_INT_P (operands[2]));
2893 amt = INTVAL (operands[2]);
2895 if (amt == 0 || amt > max_shift)
2900 output_asm_insn ("# ignored undefined behaviour left shift "
2901 "of %1 by %2", operands);
2904 output_asm_insn ("# ignored undefined behaviour arithmetic right "
2905 "shift of %1 by %2", operands);
2908 output_asm_insn ("# ignored undefined behaviour logical right shift "
2909 "of %1 by %2", operands);
2919 if (!msp430x && mode == HImode)
2920 for (i = 0; i < amt; i++)
2921 output_asm_insn ("RLA.W\t%0", operands);
2922 else if (mode == SImode)
2923 for (i = 0; i < amt; i++)
2924 output_asm_insn ("RLA%X0.W\t%L0 { RLC%X0.W\t%H0", operands);
2926 /* Catch unhandled cases. */
2929 else if (code == ASHIFTRT)
2931 if (!msp430x && mode == HImode)
2932 for (i = 0; i < amt; i++)
2933 output_asm_insn ("RRA.W\t%0", operands);
2934 else if (mode == SImode)
2935 for (i = 0; i < amt; i++)
2936 output_asm_insn ("RRA%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
2940 else if (code == LSHIFTRT)
2942 if (!msp430x && mode == HImode)
2943 for (i = 0; i < amt; i++)
2944 output_asm_insn ("CLRC { RRC.W\t%0", operands);
2945 else if (mode == SImode)
2946 for (i = 0; i < amt; i++)
2947 output_asm_insn ("CLRC { RRC%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
2948 /* FIXME: Why doesn't "RRUX.W\t%H0 { RRC%X0.W\t%L0" work for msp430x?
2949 It causes execution timeouts e.g. pr41963.c. */
2951 else if (msp430x && mode == SImode)
2952 for (i = 0; i < amt; i++)
2953 output_asm_insn ("RRUX.W\t%H0 { RRC%X0.W\t%L0", operands);
2961 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
2963 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
2965 /* constants we're looking for, not constants which are allowed. */
2966 int const_op_idx = 1;
2968 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
2971 if (GET_CODE (operands[const_op_idx]) != REG
2972 && GET_CODE (operands[const_op_idx]) != MEM)
2973 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
2976 /* Simplify_gen_subreg() doesn't handle memory references the way we
2977 need it to below, so we use this function for when we must get a
2978 valid subreg in a "natural" state. */
2980 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
2983 gcc_assert (mode == HImode);
2985 if (GET_CODE (r) == SUBREG
2986 && SUBREG_BYTE (r) == 0)
2988 rtx ireg = SUBREG_REG (r);
2989 machine_mode imode = GET_MODE (ireg);
2991 /* special case for (HI (SI (PSI ...), 0)) */
2992 if (imode == PSImode
2995 rv = gen_rtx_SUBREG (mode, ireg, byte);
2997 rv = simplify_gen_subreg (mode, ireg, imode, byte);
2999 else if (GET_CODE (r) == MEM)
3001 /* When byte == 2, we can be certain that we were already called with an
3002 identical rtx with byte == 0. So we don't need to do anything to
3003 get a 2 byte offset of a (mem (post_inc)) rtx, since the address has
3004 already been offset by the post_inc itself. */
3005 if (GET_CODE (XEXP (r, 0)) == POST_INC && byte == 2)
3007 rv = adjust_address (r, mode, byte);
3009 else if (GET_CODE (r) == SYMBOL_REF
3010 && (byte == 0 || byte == 2)
3013 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
3014 rv = gen_rtx_CONST (HImode, r);
3017 rv = simplify_gen_subreg (mode, r, omode, byte);
3026 msp430_split_addsi (rtx *operands)
3028 operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
3029 operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
3030 operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
3031 operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
3032 operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
3033 operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
3035 /* BZ 64160: Do not use this splitter when the dest partially overlaps the
3037 if (reg_overlap_mentioned_p (operands[3], operands[7])
3038 || reg_overlap_mentioned_p (operands[3], operands[8]))
3041 if (GET_CODE (operands[5]) == CONST_INT)
3042 operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
3043 /* Handle post_inc, for example:
3046 (mem:SI (post_inc:PSI (reg:PSI))))). */
3047 else if (MEM_P (operands[5]) && GET_CODE (XEXP (operands[5], 0)) == POST_INC)
3049 /* Strip out the post_inc from (mem (post_inc (reg))). */
3050 operands[9] = XEXP (XEXP (operands[5], 0), 0);
3051 operands[9] = gen_rtx_MEM (HImode, operands[9]);
3052 /* Then zero extend as normal. */
3053 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[9]);
3056 operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
3060 /* Called by movsi_x to generate the HImode operands. */
3062 msp430_split_movsi (rtx *operands)
3064 rtx op00, op02, op10, op12;
3066 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
3067 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
3069 if (GET_CODE (operands[1]) == CONST
3070 || GET_CODE (operands[1]) == SYMBOL_REF)
3072 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
3074 op10 = gen_rtx_CONST (HImode, op10);
3075 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
3077 op12 = gen_rtx_CONST (HImode, op12);
3081 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
3082 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
3085 if (rtx_equal_p (operands[0], operands[1]))
3092 else if (rtx_equal_p (op00, op12)
3093 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
3094 || (REG_P (op00) && reg_mentioned_p (op00, op10))
3095 /* Or storing (rN) into mem (rN). */
3096 || (REG_P (op10) && reg_mentioned_p (op10, op00)))
3113 /* The MSPABI specifies the names of various helper functions, many of
3114 which are compatible with GCC's helpers. This table maps the GCC
3115 name to the MSPABI name. */
3118 char const * const gcc_name;
3119 char const * const ti_name;
3121 helper_function_name_mappings[] =
3123 /* Floating point to/from integer conversions. */
3124 { "__truncdfsf2", "__mspabi_cvtdf" },
3125 { "__extendsfdf2", "__mspabi_cvtfd" },
3126 { "__fixdfhi", "__mspabi_fixdi" },
3127 { "__fixdfsi", "__mspabi_fixdli" },
3128 { "__fixdfdi", "__mspabi_fixdlli" },
3129 { "__fixunsdfhi", "__mspabi_fixdu" },
3130 { "__fixunsdfsi", "__mspabi_fixdul" },
3131 { "__fixunsdfdi", "__mspabi_fixdull" },
3132 { "__fixsfhi", "__mspabi_fixfi" },
3133 { "__fixsfsi", "__mspabi_fixfli" },
3134 { "__fixsfdi", "__mspabi_fixflli" },
3135 { "__fixunsfhi", "__mspabi_fixfu" },
3136 { "__fixunsfsi", "__mspabi_fixful" },
3137 { "__fixunsfdi", "__mspabi_fixfull" },
3138 { "__floathisf", "__mspabi_fltif" },
3139 { "__floatsisf", "__mspabi_fltlif" },
3140 { "__floatdisf", "__mspabi_fltllif" },
3141 { "__floathidf", "__mspabi_fltid" },
3142 { "__floatsidf", "__mspabi_fltlid" },
3143 { "__floatdidf", "__mspabi_fltllid" },
3144 { "__floatunhisf", "__mspabi_fltuf" },
3145 { "__floatunsisf", "__mspabi_fltulf" },
3146 { "__floatundisf", "__mspabi_fltullf" },
3147 { "__floatunhidf", "__mspabi_fltud" },
3148 { "__floatunsidf", "__mspabi_fltuld" },
3149 { "__floatundidf", "__mspabi_fltulld" },
3151 /* Floating point comparisons. */
3152 /* GCC uses individual functions for each comparison, TI uses one
3153 compare <=> function. */
3155 /* Floating point arithmetic. */
3156 { "__adddf3", "__mspabi_addd" },
3157 { "__addsf3", "__mspabi_addf" },
3158 { "__divdf3", "__mspabi_divd" },
3159 { "__divsf3", "__mspabi_divf" },
3160 { "__muldf3", "__mspabi_mpyd" },
3161 { "__mulsf3", "__mspabi_mpyf" },
3162 { "__subdf3", "__mspabi_subd" },
3163 { "__subsf3", "__mspabi_subf" },
3164 /* GCC does not use helper functions for negation. */
3166 /* Integer multiply, divide, remainder. */
3167 { "__mulhi3", "__mspabi_mpyi" },
3168 { "__mulsi3", "__mspabi_mpyl" },
3169 { "__muldi3", "__mspabi_mpyll" },
3171 /* Clarify signed vs unsigned first. */
3172 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
3174 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
3178 { "__divhi3", "__mspabi_divi" },
3179 { "__divsi3", "__mspabi_divli" },
3180 { "__divdi3", "__mspabi_divlli" },
3181 { "__udivhi3", "__mspabi_divu" },
3182 { "__udivsi3", "__mspabi_divul" },
3183 { "__udivdi3", "__mspabi_divull" },
3184 { "__modhi3", "__mspabi_remi" },
3185 { "__modsi3", "__mspabi_remli" },
3186 { "__moddi3", "__mspabi_remlli" },
3187 { "__umodhi3", "__mspabi_remu" },
3188 { "__umodsi3", "__mspabi_remul" },
3189 { "__umoddi3", "__mspabi_remull" },
3191 /* Bitwise operations. */
3192 /* Rotation - no rotation support yet. */
3193 /* Logical left shift - gcc already does these itself. */
3194 /* Arithmetic left shift - gcc already does these itself. */
3195 /* Arithmetic right shift - gcc already does these itself. */
3200 /* Returns true if the current MCU supports an F5xxx series
3201 hardware multiper. */
3204 msp430_use_f5_series_hwmult (void)
3206 static const char * cached_match = NULL;
3207 static bool cached_result;
3209 if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
3212 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3215 if (target_mcu == cached_match)
3216 return cached_result;
3218 cached_match = target_mcu;
3220 if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
3221 return cached_result = true;
3222 if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
3223 return cached_result = true;
3224 if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
3225 return cached_result = true;
3227 msp430_extract_mcu_data (target_mcu);
3229 if (extracted_mcu_data.name != NULL)
3230 return cached_result = extracted_mcu_data.hwmpy == 8;
3232 return cached_result = false;
3235 /* Returns true if the current MCU has a second generation
3236 32-bit hardware multiplier. */
3239 use_32bit_hwmult (void)
3241 static const char * cached_match = NULL;
3242 static bool cached_result;
3244 if (msp430_hwmult_type == MSP430_HWMULT_LARGE)
3247 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3250 if (target_mcu == cached_match)
3251 return cached_result;
3253 cached_match = target_mcu;
3255 msp430_extract_mcu_data (target_mcu);
3256 if (extracted_mcu_data.name != NULL)
3257 return cached_result = extracted_mcu_data.hwmpy == 4;
3259 return cached_result = false;
3262 /* Returns true if the current MCU does not have a
3263 hardware multiplier of any kind. */
3266 msp430_has_hwmult (void)
3268 static const char * cached_match = NULL;
3269 static bool cached_result;
3271 if (msp430_hwmult_type == MSP430_HWMULT_NONE)
3274 /* TRUE for any other explicit hwmult specified. */
3275 if (msp430_hwmult_type != MSP430_HWMULT_AUTO)
3278 /* Now handle -mhwmult=auto. */
3279 if (target_mcu == NULL)
3282 if (target_mcu == cached_match)
3283 return cached_result;
3285 cached_match = target_mcu;
3287 msp430_extract_mcu_data (target_mcu);
3288 if (extracted_mcu_data.name != NULL)
3289 return cached_result = extracted_mcu_data.hwmpy != 0;
3291 /* If we do not recognise the MCU name, we assume that it does not support
3292 any kind of hardware multiply - this is the safest assumption to make. */
3293 return cached_result = false;
3296 /* This function does the same as the default, but it will replace GCC
3297 function names with the MSPABI-specified ones. */
3300 msp430_output_labelref (FILE *file, const char *name)
3304 for (i = 0; helper_function_name_mappings[i].gcc_name; i++)
3305 if (strcmp (helper_function_name_mappings[i].gcc_name, name) == 0)
3307 name = helper_function_name_mappings[i].ti_name;
3311 /* If we have been given a specific MCU name then we may be
3312 able to make use of its hardware multiply capabilities. */
3313 if (msp430_has_hwmult ())
3315 if (strcmp ("__mspabi_mpyi", name) == 0)
3317 if (msp430_use_f5_series_hwmult ())
3318 name = "__mulhi2_f5";
3322 else if (strcmp ("__mspabi_mpyl", name) == 0)
3324 if (msp430_use_f5_series_hwmult ())
3325 name = "__mulsi2_f5";
3326 else if (use_32bit_hwmult ())
3327 name = "__mulsi2_hw32";
3333 if (user_label_prefix[0] != 0)
3334 fputs (user_label_prefix, file);
3339 /* Common code for msp430_print_operand... */
3342 msp430_print_operand_raw (FILE * file, rtx op)
3346 switch (GET_CODE (op))
3349 fprintf (file, "%s", reg_names[REGNO (op)]);
3355 fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
3357 fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
3365 output_addr_const (file, op);
3369 print_rtl (file, op);
3374 #undef TARGET_ASM_ALIGNED_PSI_OP
3375 #define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
3376 #undef TARGET_ASM_UNALIGNED_PSI_OP
3377 #define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
3379 #undef TARGET_PRINT_OPERAND_ADDRESS
3380 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
3382 /* Output to stdio stream FILE the assembler syntax for an
3383 instruction operand that is a memory reference whose address
3387 msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
3389 switch (GET_CODE (addr))
3392 msp430_print_operand_raw (file, XEXP (addr, 1));
3393 gcc_assert (REG_P (XEXP (addr, 0)));
3394 fprintf (file, "(%s)", reg_names[REGNO (XEXP (addr, 0))]);
3398 fprintf (file, "@");
3402 fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
3409 fprintf (file, "&");
3416 msp430_print_operand_raw (file, addr);
3419 /* We can only allow signed 15-bit indexes i.e. +/-32K. */
3421 msp430_check_index_not_high_mem (rtx op)
3423 if (CONST_INT_P (op)
3424 && IN_RANGE (INTVAL (op), HOST_WIDE_INT_M1U << 15, (1 << 15) - 1))
3429 /* If this returns true, we don't need a 430X insn. */
3431 msp430_check_plus_not_high_mem (rtx op)
3433 if (GET_CODE (op) != PLUS)
3435 rtx op0 = XEXP (op, 0);
3436 rtx op1 = XEXP (op, 1);
3437 if (SYMBOL_REF_P (op0)
3438 && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM)
3439 && msp430_check_index_not_high_mem (op1))
3444 /* Determine whether an RTX is definitely not a MEM referencing an address in
3445 the upper memory region. Returns true if we've decided the address will be
3446 in the lower memory region, or the RTX is not a MEM. Returns false
3448 The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
3449 involving a symbol_ref here. */
3451 msp430_op_not_in_high_mem (rtx op)
3455 if (!TARGET_LARGE || !MEM_P (op))
3460 if (SYMBOL_REF_P (op0) && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM))
3461 /* msp430_encode_section_info decided this mem will be in lower
3465 /* Check possibilites for (mem (plus)).
3466 e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2. */
3467 if (msp430_check_plus_not_high_mem (op0)
3468 || ((GET_CODE (op0) == CONST)
3469 && msp430_check_plus_not_high_mem (XEXP (op0, 0))))
3472 /* An absolute 16-bit address is allowed. */
3473 if ((CONST_INT_P (op0) && (IN_RANGE (INTVAL (op0), 0, (1 << 16) - 1))))
3476 /* Return false when undecided. */
3480 #undef TARGET_PRINT_OPERAND
3481 #define TARGET_PRINT_OPERAND msp430_print_operand
3483 /* A low 16-bits of int/lower of register pair
3484 B high 16-bits of int/higher of register pair
3485 C bits 32-47 of a 64-bit value/reg 3 of a DImode value
3486 D bits 48-63 of a 64-bit value/reg 4 of a DImode value
3487 H like %B (for backwards compatibility)
3489 J an integer without a # prefix
3490 L like %A (for backwards compatibility)
3491 O offset of the top of the stack
3492 Q like X but generates an A postfix
3493 R inverse of condition code, unsigned.
3495 X X instruction postfix in large mode
3498 b .B or .W or .A, depending upon the mode
3500 r inverse of condition code
3501 x like X but only for pointers. */
3504 msp430_print_operand (FILE * file, rtx op, int letter)
3508 /* We can't use c, n, a, or l. */
3512 gcc_assert (CONST_INT_P (op));
3513 /* Print the constant value, less one. */
3514 fprintf (file, "#%ld", INTVAL (op) - 1);
3517 gcc_assert (CONST_INT_P (op));
3518 /* Print the constant value, less four. */
3519 fprintf (file, "#%ld", INTVAL (op) - 4);
3522 gcc_assert (CONST_INT_P (op));
3523 /* Print the constant value, less 16. */
3524 fprintf (file, "#%ld", INTVAL (op) - 16);
3527 if (GET_CODE (op) == CONST_INT)
3529 /* Inverse of constants */
3530 int i = INTVAL (op);
3531 fprintf (file, "%d", ~i);
3536 case 'r': /* Conditional jump where the condition is reversed. */
3537 switch (GET_CODE (op))
3539 case EQ: fprintf (file, "NE"); break;
3540 case NE: fprintf (file, "EQ"); break;
3541 case GEU: fprintf (file, "LO"); break;
3542 case LTU: fprintf (file, "HS"); break;
3543 case GE: fprintf (file, "L"); break;
3544 case LT: fprintf (file, "GE"); break;
3545 /* Assume these have reversed operands. */
3546 case GTU: fprintf (file, "HS"); break;
3547 case LEU: fprintf (file, "LO"); break;
3548 case GT: fprintf (file, "GE"); break;
3549 case LE: fprintf (file, "L"); break;
3551 msp430_print_operand_raw (file, op);
3555 case 'R': /* Conditional jump where the operands are reversed. */
3556 switch (GET_CODE (op))
3558 case GTU: fprintf (file, "LO"); break;
3559 case LEU: fprintf (file, "HS"); break;
3560 case GT: fprintf (file, "L"); break;
3561 case LE: fprintf (file, "GE"); break;
3563 msp430_print_operand_raw (file, op);
3567 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
3568 gcc_assert (CONST_INT_P (op));
3569 fprintf (file, "#%d", 1 << INTVAL (op));
3572 switch (GET_MODE (op))
3574 case E_QImode: fprintf (file, ".B"); return;
3575 case E_HImode: fprintf (file, ".W"); return;
3576 case E_PSImode: fprintf (file, ".A"); return;
3577 case E_SImode: fprintf (file, ".A"); return;
3582 case 'L': /* Low half. */
3583 switch (GET_CODE (op))
3586 op = adjust_address (op, Pmode, 0);
3591 op = GEN_INT (INTVAL (op) & 0xffff);
3595 /* If you get here, figure out a test case :-) */
3600 case 'H': /* high half */
3601 switch (GET_CODE (op))
3604 /* We don't need to adjust the address for post_inc. */
3605 op = adjust_address (op, Pmode,
3606 (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 2);
3609 op = gen_rtx_REG (Pmode, REGNO (op) + 1);
3612 op = GEN_INT (INTVAL (op) >> 16);
3616 /* If you get here, figure out a test case :-) */
3621 switch (GET_CODE (op))
3624 op = adjust_address (op, Pmode,
3625 (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 4);
3628 op = gen_rtx_REG (Pmode, REGNO (op) + 2);
3631 op = GEN_INT ((long long) INTVAL (op) >> 32);
3635 /* If you get here, figure out a test case :-) */
3640 switch (GET_CODE (op))
3643 op = adjust_address (op, Pmode,
3644 (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 6);
3647 op = gen_rtx_REG (Pmode, REGNO (op) + 3);
3650 op = GEN_INT ((long long) INTVAL (op) >> 48);
3654 /* If you get here, figure out a test case :-) */
3660 /* This is used to turn, for example, an ADD opcode into an ADDX
3661 opcode when we're using 20-bit addresses.
3662 This can be used for insns which have only one operand which might be
3664 If an insn has two different operands which could be memory operands,
3665 then the "Yx" constraint must be used to determine if the X suffix is
3666 required by checking both operands. */
3667 if (GET_MODE (op) == PSImode
3668 || !msp430_op_not_in_high_mem (op))
3669 fprintf (file, "X");
3673 /* Similarly, but only for PSImodes. BIC, and other insn patterns using
3674 the QHI mode iterator (which includes, QI, HI, and PSImode) use
3676 if (GET_MODE (op) == PSImode)
3677 fprintf (file, "X");
3681 /* Likewise, for BR -> BRA. */
3683 fprintf (file, "A");
3687 /* Computes the offset to the top of the stack for the current frame.
3688 This has to be done here rather than in, say, msp430_expand_builtin()
3689 because builtins are expanded before the frame layout is
3691 fprintf (file, "%d",
3692 msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
3693 STACK_POINTER_REGNUM)
3694 - (TARGET_LARGE ? 4 : 2));
3698 gcc_assert (GET_CODE (op) == CONST_INT);
3702 output_operand_lossage ("invalid operand prefix");
3706 switch (GET_CODE (op))
3709 msp430_print_operand_raw (file, op);
3713 addr = XEXP (op, 0);
3714 msp430_print_operand_addr (file, GET_MODE (op), addr);
3718 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
3721 switch (INTVAL (XEXP (op, 2)))
3724 fprintf (file, "#lo (");
3725 msp430_print_operand_raw (file, XEXP (op, 0));
3726 fprintf (file, ")");
3730 fprintf (file, "#hi (");
3731 msp430_print_operand_raw (file, XEXP (op, 0));
3732 fprintf (file, ")");
3736 output_operand_lossage ("invalid zero extract");
3746 fprintf (file, "#");
3747 msp430_print_operand_raw (file, op);
3750 case EQ: fprintf (file, "EQ"); break;
3751 case NE: fprintf (file, "NE"); break;
3752 case GEU: fprintf (file, "HS"); break;
3753 case LTU: fprintf (file, "LO"); break;
3754 case GE: fprintf (file, "GE"); break;
3755 case LT: fprintf (file, "L"); break;
3758 print_rtl (file, op);
3767 msp430_return_addr_rtx (int count)
3773 ra_size = TARGET_LARGE ? 4 : 2;
3774 if (crtl->args.pretend_args_size)
3777 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx,
3778 GEN_INT (- ra_size)));
3782 msp430_incoming_return_addr_rtx (void)
3784 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
3787 /* If the path to the MSP430-GCC support files has been found by examining
3788 an environment variable (see msp430_check_env_var_for_devices in
3789 msp430-devices.c), or -mdevices-csv-loc=, register this path as an include
3790 directory so the user can #include msp430.h without needing to specify the
3791 path to the support files with -I. */
3793 msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
3794 const char *iprefix ATTRIBUTE_UNUSED,
3795 int stdinc ATTRIBUTE_UNUSED)
3798 if (msp430_devices_csv_loc)
3799 include_dir = xstrdup (msp430_devices_csv_loc);
3800 else if (msp430_check_env_var_for_devices (&include_dir))
3802 include_dir = msp430_dirname (include_dir);
3804 include_dir = update_path (include_dir, "");
3805 add_path (include_dir, INC_SYSTEM, false, false);
3808 /* Instruction generation stuff. */
3810 /* Generate a sequence of instructions to sign-extend an HI
3811 value into an SI value. Handles the tricky case where
3812 we are overwriting the destination. */
3815 msp430x_extendhisi (rtx * operands)
3817 if (REGNO (operands[0]) == REGNO (operands[1]))
3818 /* Low word of dest == source word. 8-byte sequence. */
3819 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0";
3822 /* Note: This sequence is approximately the same length as invoking a helper
3823 function to perform the sign-extension, as in:
3827 CALL __mspabi_srai_15
3830 but this version does not involve any function calls or using argument
3831 registers, so it reduces register pressure. 10-byte sequence. */
3832 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 "
3833 "{ INV.W\t%H0, %H0";
3835 if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
3836 /* High word of dest == source word. 6-byte sequence. */
3837 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0";
3839 /* No overlap between dest and source. 8-byte sequence. */
3840 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0";
3843 /* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */
3845 #undef TARGET_CAN_CHANGE_MODE_CLASS
3846 #define TARGET_CAN_CHANGE_MODE_CLASS msp430_can_change_mode_class
3849 msp430_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t)
3851 if ((to == PSImode && from == SImode)
3852 || (to == SImode && from == PSImode)
3853 || (to == DImode && from == PSImode)
3854 || (to == PSImode && from == DImode))
3859 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
3860 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
3862 struct gcc_target targetm = TARGET_INITIALIZER;
3864 #include "gt-msp430.h"