1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2015 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/>. */
23 #include "coretypes.h"
32 #include "fold-const.h"
33 #include "stor-layout.h"
37 #include "hard-reg-set.h"
38 #include "insn-config.h"
39 #include "conditions.h"
41 #include "insn-attr.h"
45 #include "statistics.h"
53 #include "insn-codes.h"
57 #include "diagnostic-core.h"
60 #include "dominance.h"
66 #include "cfgcleanup.h"
68 #include "basic-block.h"
74 #include "target-def.h"
75 #include "langhooks.h"
76 #include "msp430-protos.h"
82 static void msp430_compute_frame_info (void);
86 /* Run-time Target Specification. */
90 struct GTY(()) machine_function
92 /* If set, the rest of the fields have been computed. */
94 /* Which registers need to be saved in the pro/epilogue. */
95 int need_to_save
[FIRST_PSEUDO_REGISTER
];
97 /* These fields describe the frame layout... */
99 /* 2/4 bytes for saved PC */
102 int framesize_locals
;
103 int framesize_outgoing
;
107 /* How much we adjust the stack when returning from an exception
112 /* This is our init_machine_status, as set in
113 msp_option_override. */
114 static struct machine_function
*
115 msp430_init_machine_status (void)
117 struct machine_function
*m
;
119 m
= ggc_cleared_alloc
<machine_function
> ();
124 #undef TARGET_OPTION_OVERRIDE
125 #define TARGET_OPTION_OVERRIDE msp430_option_override
127 static const char * msp430_mcu_names
[] =
129 "msp430afe221", "msp430afe222", "msp430afe223", "msp430afe231",
130 "msp430afe232", "msp430afe233", "msp430afe251", "msp430afe252",
131 "msp430afe253", "msp430c091", "msp430c092", "msp430c111",
132 "msp430c1111", "msp430c112", "msp430c1121", "msp430c1331",
133 "msp430c1351", "msp430c311s", "msp430c312", "msp430c313",
134 "msp430c314", "msp430c315", "msp430c323", "msp430c325",
135 "msp430c336", "msp430c337", "msp430c412", "msp430c413",
136 "msp430e112", "msp430e313", "msp430e315", "msp430e325",
137 "msp430e337", "msp430f110", "msp430f1101", "msp430f1101a",
138 "msp430f1111", "msp430f1111a", "msp430f112", "msp430f1121",
139 "msp430f1121a", "msp430f1122", "msp430f1132", "msp430f122",
140 "msp430f1222", "msp430f123", "msp430f1232", "msp430f133",
141 "msp430f135", "msp430f147", "msp430f1471", "msp430f148",
142 "msp430f1481", "msp430f149", "msp430f1491", "msp430f155",
143 "msp430f156", "msp430f157", "msp430f1610", "msp430f1611",
144 "msp430f1612", "msp430f167", "msp430f168", "msp430f169",
145 "msp430f2001", "msp430f2002", "msp430f2003", "msp430f2011",
146 "msp430f2012", "msp430f2013", "msp430f2101", "msp430f2111",
147 "msp430f2112", "msp430f2121", "msp430f2122", "msp430f2131",
148 "msp430f2132", "msp430f2232", "msp430f2234", "msp430f2252",
149 "msp430f2254", "msp430f2272", "msp430f2274", "msp430f233",
150 "msp430f2330", "msp430f235", "msp430f2350", "msp430f2370",
151 "msp430f2410", "msp430f247", "msp430f2471", "msp430f248",
152 "msp430f2481", "msp430f249", "msp430f2491", "msp430f412",
153 "msp430f413", "msp430f4132", "msp430f415", "msp430f4152",
154 "msp430f417", "msp430f423", "msp430f423a", "msp430f425",
155 "msp430f4250", "msp430f425a", "msp430f4260", "msp430f427",
156 "msp430f4270", "msp430f427a", "msp430f435", "msp430f4351",
157 "msp430f436", "msp430f4361", "msp430f437", "msp430f4371",
158 "msp430f438", "msp430f439", "msp430f447", "msp430f448",
159 "msp430f4481", "msp430f449", "msp430f4491", "msp430f477",
160 "msp430f478", "msp430f4783", "msp430f4784", "msp430f479",
161 "msp430f4793", "msp430f4794", "msp430fe423", "msp430fe4232",
162 "msp430fe423a", "msp430fe4242", "msp430fe425", "msp430fe4252",
163 "msp430fe425a", "msp430fe427", "msp430fe4272", "msp430fe427a",
164 "msp430fg4250", "msp430fg4260", "msp430fg4270", "msp430fg437",
165 "msp430fg438", "msp430fg439", "msp430fg477", "msp430fg478",
166 "msp430fg479", "msp430fw423", "msp430fw425", "msp430fw427",
167 "msp430fw428", "msp430fw429", "msp430g2001", "msp430g2101",
168 "msp430g2102", "msp430g2111", "msp430g2112", "msp430g2113",
169 "msp430g2121", "msp430g2131", "msp430g2132", "msp430g2152",
170 "msp430g2153", "msp430g2201", "msp430g2202", "msp430g2203",
171 "msp430g2210", "msp430g2211", "msp430g2212", "msp430g2213",
172 "msp430g2221", "msp430g2230", "msp430g2231", "msp430g2232",
173 "msp430g2233", "msp430g2252", "msp430g2253", "msp430g2302",
174 "msp430g2303", "msp430g2312", "msp430g2313", "msp430g2332",
175 "msp430g2333", "msp430g2352", "msp430g2353", "msp430g2402",
176 "msp430g2403", "msp430g2412", "msp430g2413", "msp430g2432",
177 "msp430g2433", "msp430g2444", "msp430g2452", "msp430g2453",
178 "msp430g2513", "msp430g2533", "msp430g2544", "msp430g2553",
179 "msp430g2744", "msp430g2755", "msp430g2855", "msp430g2955",
180 "msp430i2020", "msp430i2021", "msp430i2030", "msp430i2031",
181 "msp430i2040", "msp430i2041", "msp430l092", "msp430p112",
182 "msp430p313", "msp430p315", "msp430p315s", "msp430p325",
183 "msp430p337", "msp430tch5e"
186 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
187 If a specific MCU has not been selected then return a generic symbol instead. */
190 msp430_mcu_name (void)
195 static char mcu_name
[64];
197 snprintf (mcu_name
, sizeof (mcu_name
) - 1, "__%s__", target_mcu
);
198 for (i
= strlen (mcu_name
); i
--;)
199 mcu_name
[i
] = TOUPPER (mcu_name
[i
]);
203 return msp430x
? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
207 msp430_option_override (void)
209 init_machine_status
= msp430_init_machine_status
;
213 if (strcasecmp (target_cpu
, "msp430x") == 0)
215 else /* target_cpu == "msp430" - already handled by the front end. */
218 /* Note - the front end has already ensured at most
219 one of target_cpu and target_mcu will be set. */
224 /* If we are given an MCU name, we assume that it supports 430X.
225 Then we check to see if it is one of the known MCUs that only
229 for (i
= ARRAY_SIZE (msp430_mcu_names
); i
--;)
230 if (strcasecmp (msp430_mcu_names
[i
], target_mcu
) == 0)
235 /* It is not an error if we do not match the MCU name. There are
239 if (TARGET_LARGE
&& !msp430x
)
240 error ("-mlarge requires a 430X-compatible -mmcu=");
242 if (msp430_code_region
== UPPER
&& ! msp430x
)
243 error ("-mcode-region=upper requires 430X-compatible cpu");
244 if (msp430_data_region
== UPPER
&& ! msp430x
)
245 error ("-mdata-region=upper requires 430X-compatible cpu");
247 if (flag_exceptions
|| flag_non_call_exceptions
248 || flag_unwind_tables
|| flag_asynchronous_unwind_tables
)
249 flag_omit_frame_pointer
= false;
251 flag_omit_frame_pointer
= true;
253 /* This is a hack to work around a problem with the newlib build
254 mechanism. Newlib always appends CFLAGS to the end of the GCC
255 command line and always sets -O2 in CFLAGS. Thus it is not
256 possible to build newlib with -Os enabled. Until now... */
257 if (TARGET_OPT_SPACE
&& optimize
< 3)
261 #undef TARGET_SCALAR_MODE_SUPPORTED_P
262 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
265 msp430_scalar_mode_supported_p (machine_mode m
)
267 if (m
== PSImode
&& msp430x
)
273 return default_scalar_mode_supported_p (m
);
280 #undef TARGET_MS_BITFIELD_LAYOUT_P
281 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
284 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED
)
293 /* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single
294 PSImode value, but not an SImode value. */
296 msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED
,
299 if (mode
== PSImode
&& msp430x
)
301 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
305 /* Implements HARD_REGNO_NREGS_HAS_PADDING. */
307 msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED
,
310 if (mode
== PSImode
&& msp430x
)
312 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
316 /* Implements HARD_REGNO_NREGS_WITH_PADDING. */
318 msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED
,
323 return msp430_hard_regno_nregs (regno
, mode
);
326 /* Implements HARD_REGNO_MODE_OK. */
328 msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED
,
331 return regno
<= (ARG_POINTER_REGNUM
- msp430_hard_regno_nregs (regno
, mode
));
334 /* Implements MODES_TIEABLE_P. */
336 msp430_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
338 if ((mode1
== PSImode
|| mode2
== SImode
)
339 || (mode1
== SImode
|| mode2
== PSImode
))
342 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
343 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
344 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
345 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
348 #undef TARGET_FRAME_POINTER_REQUIRED
349 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
352 msp430_frame_pointer_required (void)
357 #undef TARGET_CAN_ELIMINATE
358 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
361 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED
,
362 const int to_reg ATTRIBUTE_UNUSED
)
367 /* Implements INITIAL_ELIMINATION_OFFSET. */
369 msp430_initial_elimination_offset (int from
, int to
)
371 int rv
= 0; /* As if arg to arg. */
373 msp430_compute_frame_info ();
377 case STACK_POINTER_REGNUM
:
378 rv
+= cfun
->machine
->framesize_outgoing
;
379 rv
+= cfun
->machine
->framesize_locals
;
381 case FRAME_POINTER_REGNUM
:
382 rv
+= cfun
->machine
->framesize_regs
;
383 /* Allow for the saved return address. */
384 rv
+= (TARGET_LARGE
? 4 : 2);
385 /* NB/ No need to allow for crtl->args.pretend_args_size.
386 GCC does that for us. */
394 case FRAME_POINTER_REGNUM
:
395 /* Allow for the fall through above. */
396 rv
-= (TARGET_LARGE
? 4 : 2);
397 rv
-= cfun
->machine
->framesize_regs
;
398 case ARG_POINTER_REGNUM
:
407 /* Named Address Space support */
410 /* Return the appropriate mode for a named address pointer. */
411 #undef TARGET_ADDR_SPACE_POINTER_MODE
412 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
413 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
414 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
417 msp430_addr_space_pointer_mode (addr_space_t addrspace
)
422 case ADDR_SPACE_GENERIC
:
424 case ADDR_SPACE_NEAR
:
431 /* Function pointers are stored in unwind_word sized
432 variables, so make sure that unwind_word is big enough. */
433 #undef TARGET_UNWIND_WORD_MODE
434 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
437 msp430_unwind_word_mode (void)
439 return TARGET_LARGE
? PSImode
: HImode
;
442 /* Determine if one named address space is a subset of another. */
443 #undef TARGET_ADDR_SPACE_SUBSET_P
444 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
446 msp430_addr_space_subset_p (addr_space_t subset
, addr_space_t superset
)
448 if (subset
== superset
)
451 return (subset
!= ADDR_SPACE_FAR
&& superset
== ADDR_SPACE_FAR
);
454 #undef TARGET_ADDR_SPACE_CONVERT
455 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
456 /* Convert from one address space to another. */
458 msp430_addr_space_convert (rtx op
, tree from_type
, tree to_type
)
460 addr_space_t from_as
= TYPE_ADDR_SPACE (TREE_TYPE (from_type
));
461 addr_space_t to_as
= TYPE_ADDR_SPACE (TREE_TYPE (to_type
));
464 if (to_as
!= ADDR_SPACE_FAR
&& from_as
== ADDR_SPACE_FAR
)
466 /* This is unpredictable, as we're truncating off usable address
470 return gen_rtx_CONST (HImode
, op
);
472 result
= gen_reg_rtx (HImode
);
473 emit_insn (gen_truncpsihi2 (result
, op
));
476 else if (to_as
== ADDR_SPACE_FAR
&& from_as
!= ADDR_SPACE_FAR
)
478 /* This always works. */
481 return gen_rtx_CONST (PSImode
, op
);
483 result
= gen_reg_rtx (PSImode
);
484 emit_insn (gen_zero_extendhipsi2 (result
, op
));
491 /* Stack Layout and Calling Conventions. */
493 /* For each function, we list the gcc version and the TI version on
494 each line, where we're converting the function names. */
495 static char const * const special_convention_function_names
[] =
497 "__muldi3", "__mspabi_mpyll",
498 "__udivdi3", "__mspabi_divull",
499 "__umoddi3", "__mspabi_remull",
500 "__divdi3", "__mspabi_divlli",
501 "__moddi3", "__mspabi_remlli",
505 "__adddf3", "__mspabi_addd",
506 "__subdf3", "__mspabi_subd",
507 "__muldf3", "__mspabi_mpyd",
508 "__divdf3", "__mspabi_divd",
513 /* TRUE if the function passed is a "speical" function. Special
514 functions pass two DImode parameters in registers. */
516 msp430_special_register_convention_p (const char *name
)
520 for (i
= 0; special_convention_function_names
[i
]; i
++)
521 if (! strcmp (name
, special_convention_function_names
[i
]))
527 #undef TARGET_FUNCTION_VALUE_REGNO_P
528 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
531 msp430_function_value_regno_p (unsigned int regno
)
537 #undef TARGET_FUNCTION_VALUE
538 #define TARGET_FUNCTION_VALUE msp430_function_value
541 msp430_function_value (const_tree ret_type
,
542 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
543 bool outgoing ATTRIBUTE_UNUSED
)
545 return gen_rtx_REG (TYPE_MODE (ret_type
), 12);
548 #undef TARGET_LIBCALL_VALUE
549 #define TARGET_LIBCALL_VALUE msp430_libcall_value
552 msp430_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
554 return gen_rtx_REG (mode
, 12);
557 /* Implements INIT_CUMULATIVE_ARGS. */
559 msp430_init_cumulative_args (CUMULATIVE_ARGS
*ca
,
560 tree fntype ATTRIBUTE_UNUSED
,
561 rtx libname ATTRIBUTE_UNUSED
,
562 tree fndecl ATTRIBUTE_UNUSED
,
563 int n_named_args ATTRIBUTE_UNUSED
)
566 memset (ca
, 0, sizeof(*ca
));
571 fname
= IDENTIFIER_POINTER (DECL_NAME (fndecl
));
573 fname
= XSTR (libname
, 0);
577 if (fname
&& msp430_special_register_convention_p (fname
))
581 /* Helper function for argument passing; this function is the common
582 code that determines where an argument will be passed. */
584 msp430_evaluate_arg (cumulative_args_t cap
,
586 const_tree type ATTRIBUTE_UNUSED
,
589 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
590 int nregs
= GET_MODE_SIZE (mode
);
602 nregs
= (nregs
+ 1) / 2;
606 /* Function is passed two DImode operands, in R8:R11 and
616 for (i
= 0; i
< 4; i
++)
617 if (! ca
->reg_used
[i
])
620 ca
->start_reg
= CA_FIRST_REG
+ i
;
625 for (i
= 0; i
< 3; i
++)
626 if (! ca
->reg_used
[i
] && ! ca
->reg_used
[i
+ 1])
629 ca
->start_reg
= CA_FIRST_REG
+ i
;
632 if (! ca
->reg_used
[3] && ca
->can_split
)
636 ca
->start_reg
= CA_FIRST_REG
+ 3;
643 if (! ca
->reg_used
[0]
644 && ! ca
->reg_used
[1]
645 && ! ca
->reg_used
[2]
646 && ! ca
->reg_used
[3])
649 ca
->start_reg
= CA_FIRST_REG
;
656 #undef TARGET_PROMOTE_PROTOTYPES
657 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
660 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED
)
665 #undef TARGET_FUNCTION_ARG
666 #define TARGET_FUNCTION_ARG msp430_function_arg
669 msp430_function_arg (cumulative_args_t cap
,
674 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
676 msp430_evaluate_arg (cap
, mode
, type
, named
);
679 return gen_rtx_REG (mode
, ca
->start_reg
);
684 #undef TARGET_ARG_PARTIAL_BYTES
685 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
688 msp430_arg_partial_bytes (cumulative_args_t cap
,
693 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
695 msp430_evaluate_arg (cap
, mode
, type
, named
);
697 if (ca
->reg_count
&& ca
->mem_count
)
698 return ca
->reg_count
* UNITS_PER_WORD
;
703 #undef TARGET_PASS_BY_REFERENCE
704 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
707 msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED
,
710 bool named ATTRIBUTE_UNUSED
)
712 return (mode
== BLKmode
713 || (type
&& TREE_CODE (type
) == RECORD_TYPE
)
714 || (type
&& TREE_CODE (type
) == UNION_TYPE
));
717 #undef TARGET_CALLEE_COPIES
718 #define TARGET_CALLEE_COPIES msp430_callee_copies
721 msp430_callee_copies (cumulative_args_t cap ATTRIBUTE_UNUSED
,
722 machine_mode mode ATTRIBUTE_UNUSED
,
723 const_tree type ATTRIBUTE_UNUSED
,
724 bool named ATTRIBUTE_UNUSED
)
729 #undef TARGET_FUNCTION_ARG_ADVANCE
730 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
733 msp430_function_arg_advance (cumulative_args_t cap
,
738 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
741 msp430_evaluate_arg (cap
, mode
, type
, named
);
743 if (ca
->start_reg
>= CA_FIRST_REG
)
744 for (i
= 0; i
< ca
->reg_count
; i
++)
745 ca
->reg_used
[i
+ ca
->start_reg
- CA_FIRST_REG
] = 1;
750 #undef TARGET_FUNCTION_ARG_BOUNDARY
751 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
754 msp430_function_arg_boundary (machine_mode mode
, const_tree type
)
757 && int_size_in_bytes (type
) > 1)
759 if (GET_MODE_BITSIZE (mode
) > 8)
764 #undef TARGET_RETURN_IN_MEMORY
765 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
768 msp430_return_in_memory (const_tree ret_type
, const_tree fntype ATTRIBUTE_UNUSED
)
770 machine_mode mode
= TYPE_MODE (ret_type
);
773 || (fntype
&& TREE_CODE (TREE_TYPE (fntype
)) == RECORD_TYPE
)
774 || (fntype
&& TREE_CODE (TREE_TYPE (fntype
)) == UNION_TYPE
))
777 if (GET_MODE_SIZE (mode
) > 8)
783 #undef TARGET_GET_RAW_ARG_MODE
784 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
787 msp430_get_raw_arg_mode (int regno
)
789 return (regno
== ARG_POINTER_REGNUM
) ? VOIDmode
: Pmode
;
792 #undef TARGET_GET_RAW_RESULT_MODE
793 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
796 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED
)
801 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
802 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
804 #include "gimplify.h"
805 #include "gimple-expr.h"
808 msp430_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
811 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
812 unsigned HOST_WIDE_INT align
, boundary
;
815 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
817 type
= build_pointer_type (type
);
819 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
820 boundary
= targetm
.calls
.function_arg_boundary (TYPE_MODE (type
), type
);
822 /* When we align parameter on stack for caller, if the parameter
823 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
824 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
826 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
827 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
829 boundary
/= BITS_PER_UNIT
;
831 /* Hoist the valist value into a temporary for the moment. */
832 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
834 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
835 requires greater alignment, we must perform dynamic alignment. */
837 && !integer_zerop (TYPE_SIZE (type
)))
839 /* FIXME: This is where this function diverts from targhooks.c:
840 std_gimplify_va_arg_expr(). It works, but I do not know why... */
841 if (! POINTER_TYPE_P (type
))
843 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
844 fold_build_pointer_plus_hwi (valist_tmp
, boundary
- 1));
845 gimplify_and_add (t
, pre_p
);
847 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
848 fold_build2 (BIT_AND_EXPR
, TREE_TYPE (valist
),
850 build_int_cst (TREE_TYPE (valist
), -boundary
)));
851 gimplify_and_add (t
, pre_p
);
857 /* If the actual alignment is less than the alignment of the type,
858 adjust the type accordingly so that we don't assume strict alignment
859 when dereferencing the pointer. */
860 boundary
*= BITS_PER_UNIT
;
861 if (boundary
< TYPE_ALIGN (type
))
863 type
= build_variant_type_copy (type
);
864 TYPE_ALIGN (type
) = boundary
;
867 /* Compute the rounded size of the type. */
868 type_size
= size_in_bytes (type
);
869 rounded_size
= round_up (type_size
, align
);
871 /* Reduce rounded_size so it's sharable with the postqueue. */
872 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
877 /* Compute new value for AP. */
878 t
= fold_build_pointer_plus (valist_tmp
, rounded_size
);
879 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
880 gimplify_and_add (t
, pre_p
);
882 addr
= fold_convert (build_pointer_type (type
), addr
);
885 addr
= build_va_arg_indirect_ref (addr
);
887 addr
= build_va_arg_indirect_ref (addr
);
892 /* Addressing Modes */
894 #undef TARGET_LEGITIMATE_ADDRESS_P
895 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
898 reg_ok_for_addr (rtx r
, bool strict
)
902 if (strict
&& rn
>= FIRST_PSEUDO_REGISTER
)
903 rn
= reg_renumber
[rn
];
904 if (strict
&& 0 <= rn
&& rn
< FIRST_PSEUDO_REGISTER
)
912 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
913 rtx x ATTRIBUTE_UNUSED
,
914 bool strict ATTRIBUTE_UNUSED
)
916 switch (GET_CODE (x
))
922 if (REG_P (XEXP (x
, 0)))
924 if (GET_MODE (x
) != GET_MODE (XEXP (x
, 0)))
926 if (!reg_ok_for_addr (XEXP (x
, 0), strict
))
928 switch (GET_CODE (XEXP (x
, 1)))
941 if (!reg_ok_for_addr (x
, strict
))
954 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
955 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p
958 msp430_addr_space_legitimate_address_p (machine_mode mode
,
961 addr_space_t as ATTRIBUTE_UNUSED
)
963 return msp430_legitimate_address_p (mode
, x
, strict
);
966 #undef TARGET_ASM_INTEGER
967 #define TARGET_ASM_INTEGER msp430_asm_integer
969 msp430_asm_integer (rtx x
, unsigned int size
, int aligned_p
)
971 int c
= GET_CODE (x
);
973 if (size
== 3 && GET_MODE (x
) == PSImode
)
979 if (c
== SYMBOL_REF
|| c
== CONST
|| c
== LABEL_REF
|| c
== CONST_INT
980 || c
== PLUS
|| c
== MINUS
)
982 fprintf (asm_out_file
, "\t.long\t");
983 output_addr_const (asm_out_file
, x
);
984 fputc ('\n', asm_out_file
);
989 return default_assemble_integer (x
, size
, aligned_p
);
992 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
993 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
995 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED
, rtx x
)
1001 #undef TARGET_LEGITIMATE_CONSTANT_P
1002 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1005 msp430_legitimate_constant (machine_mode mode
, rtx x
)
1007 return ! CONST_INT_P (x
)
1009 /* GCC does not know the width of the PSImode, so make
1010 sure that it does not try to use a constant value that
1012 || (INTVAL (x
) < (1 << 20) && INTVAL (x
) >= (-1 << 20));
1016 #undef TARGET_RTX_COSTS
1017 #define TARGET_RTX_COSTS msp430_rtx_costs
1019 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED
,
1021 int outer_code ATTRIBUTE_UNUSED
,
1022 int opno ATTRIBUTE_UNUSED
,
1024 bool speed ATTRIBUTE_UNUSED
)
1029 if (GET_MODE (x
) == SImode
&& outer_code
== SET
)
1031 *total
= COSTS_N_INSNS (4);
1040 *total
= COSTS_N_INSNS (100);
1048 /* Function Entry and Exit */
1050 /* The MSP430 call frame looks like this:
1053 +--------------------+
1057 +--------------------+ <-- "arg pointer"
1059 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1061 +--------------------+
1062 | SR if this func has|
1063 | been called via an |
1065 +--------------------+ <-- SP before prologue, also AP
1067 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1069 +--------------------+ <-- "frame pointer"
1073 +--------------------+
1077 +--------------------+ <-- SP during function
1082 /* We use this to wrap all emitted insns in the prologue, so they get
1083 the "frame-related" (/f) flag set. */
1087 RTX_FRAME_RELATED_P (x
) = 1;
1091 /* This is the one spot that decides if a register is to be saved and
1092 restored in the prologue/epilogue. */
1094 msp430_preserve_reg_p (int regno
)
1096 /* PC, SP, SR, and the constant generator. */
1100 /* FIXME: add interrupt, EH, etc. */
1101 if (crtl
->calls_eh_return
)
1104 /* Shouldn't be more than the above, but just in case... */
1105 if (fixed_regs
[regno
])
1108 /* Interrupt handlers save all registers they use, even
1109 ones which are call saved. If they call other functions
1110 then *every* register is saved. */
1111 if (msp430_is_interrupt_func ())
1112 return ! crtl
->is_leaf
|| df_regs_ever_live_p (regno
);
1114 if (!call_used_regs
[regno
]
1115 && df_regs_ever_live_p (regno
))
1121 /* Compute all the frame-related fields in our machine_function
1124 msp430_compute_frame_info (void)
1128 cfun
->machine
->computed
= 1;
1129 cfun
->machine
->framesize_regs
= 0;
1130 cfun
->machine
->framesize_locals
= get_frame_size ();
1131 cfun
->machine
->framesize_outgoing
= crtl
->outgoing_args_size
;
1133 for (i
= 0; i
< ARG_POINTER_REGNUM
; i
++)
1134 if (msp430_preserve_reg_p (i
))
1136 cfun
->machine
->need_to_save
[i
] = 1;
1137 cfun
->machine
->framesize_regs
+= (TARGET_LARGE
? 4 : 2);
1140 cfun
->machine
->need_to_save
[i
] = 0;
1142 if ((cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
) & 1)
1143 cfun
->machine
->framesize_locals
++;
1145 cfun
->machine
->framesize
= (cfun
->machine
->framesize_regs
1146 + cfun
->machine
->framesize_locals
1147 + cfun
->machine
->framesize_outgoing
);
1150 /* Attribute Handling. */
1152 const char * const ATTR_INTR
= "interrupt";
1153 const char * const ATTR_WAKEUP
= "wakeup";
1154 const char * const ATTR_NAKED
= "naked";
1155 const char * const ATTR_REENT
= "reentrant";
1156 const char * const ATTR_CRIT
= "critical";
1157 const char * const ATTR_LOWER
= "lower";
1158 const char * const ATTR_UPPER
= "upper";
1159 const char * const ATTR_EITHER
= "either";
1162 has_attr (const char * attr
, tree decl
)
1164 if (decl
== NULL_TREE
)
1166 return lookup_attribute (attr
, DECL_ATTRIBUTES (decl
)) != NULL_TREE
;
1170 is_interrupt_func (tree decl
= current_function_decl
)
1172 return has_attr (ATTR_INTR
, decl
);
1175 /* Returns true if the current function has the "interrupt" attribute. */
1178 msp430_is_interrupt_func (void)
1180 return is_interrupt_func (current_function_decl
);
1184 is_wakeup_func (tree decl
= current_function_decl
)
1186 return is_interrupt_func (decl
) && has_attr (ATTR_WAKEUP
, decl
);
1190 is_naked_func (tree decl
= current_function_decl
)
1192 return has_attr (ATTR_NAKED
, decl
);
1196 is_reentrant_func (tree decl
= current_function_decl
)
1198 return has_attr (ATTR_REENT
, decl
);
1202 is_critical_func (tree decl
= current_function_decl
)
1204 return has_attr (ATTR_CRIT
, decl
);
1207 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1208 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args
1211 msp430_allocate_stack_slots_for_args (void)
1213 /* Naked functions should not allocate stack slots for arguments. */
1214 return ! is_naked_func ();
1217 /* Verify MSP430 specific attributes. */
1218 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1221 msp430_attr (tree
* node
,
1224 int flags ATTRIBUTE_UNUSED
,
1225 bool * no_add_attrs
)
1227 gcc_assert (DECL_P (* node
));
1231 gcc_assert (TREE_NAME_EQ (name
, ATTR_INTR
));
1233 tree value
= TREE_VALUE (args
);
1235 switch (TREE_CODE (value
))
1238 if ( strcmp (TREE_STRING_POINTER (value
), "reset")
1239 && strcmp (TREE_STRING_POINTER (value
), "nmi")
1240 && strcmp (TREE_STRING_POINTER (value
), "watchdog"))
1241 /* Allow the attribute to be added - the linker script
1242 being used may still recognise this name. */
1243 warning (OPT_Wattributes
,
1244 "unrecognised interrupt vector argument of %qE attribute",
1249 if (wi::gtu_p (value
, 63))
1250 /* Allow the attribute to be added - the linker script
1251 being used may still recognise this value. */
1252 warning (OPT_Wattributes
,
1253 "numeric argument of %qE attribute must be in range 0..63",
1258 warning (OPT_Wattributes
,
1259 "argument of %qE attribute is not a string constant or number",
1261 *no_add_attrs
= true;
1266 const char * message
= NULL
;
1268 if (TREE_CODE (* node
) != FUNCTION_DECL
)
1270 message
= "%qE attribute only applies to functions";
1272 else if (TREE_NAME_EQ (name
, ATTR_INTR
))
1274 if (TREE_CODE (TREE_TYPE (* node
)) == FUNCTION_TYPE
1275 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node
))))
1276 message
= "interrupt handlers must be void";
1278 else if (TREE_NAME_EQ (name
, ATTR_REENT
))
1280 if (is_naked_func (* node
))
1281 message
= "naked functions cannot be reentrant";
1282 else if (is_critical_func (* node
))
1283 message
= "critical functions cannot be reentrant";
1285 else if (TREE_NAME_EQ (name
, ATTR_CRIT
))
1287 if (is_naked_func (* node
))
1288 message
= "naked functions cannot be critical";
1289 else if (is_reentrant_func (* node
))
1290 message
= "reentranct functions cannot be critical";
1292 else if (TREE_NAME_EQ (name
, ATTR_NAKED
))
1294 if (is_critical_func (* node
))
1295 message
= "critical functions cannot be naked";
1296 else if (is_reentrant_func (* node
))
1297 message
= "reentrant functions cannot be naked";
1302 warning (OPT_Wattributes
, message
, name
);
1303 * no_add_attrs
= true;
1310 msp430_section_attr (tree
* node
,
1313 int flags ATTRIBUTE_UNUSED
,
1314 bool * no_add_attrs ATTRIBUTE_UNUSED
)
1316 gcc_assert (DECL_P (* node
));
1317 gcc_assert (args
== NULL
);
1319 const char * message
= NULL
;
1321 if (TREE_NAME_EQ (name
, ATTR_UPPER
))
1323 if (has_attr (ATTR_LOWER
, * node
))
1324 message
= "already marked with 'lower' attribute";
1325 else if (has_attr (ATTR_EITHER
, * node
))
1326 message
= "already marked with 'either' attribute";
1328 message
= "upper attribute needs a 430X cpu";
1330 else if (TREE_NAME_EQ (name
, ATTR_LOWER
))
1332 if (has_attr (ATTR_UPPER
, * node
))
1333 message
= "already marked with 'upper' attribute";
1334 else if (has_attr (ATTR_EITHER
, * node
))
1335 message
= "already marked with 'either' attribute";
1339 gcc_assert (TREE_NAME_EQ (name
, ATTR_EITHER
));
1341 if (has_attr (ATTR_LOWER
, * node
))
1342 message
= "already marked with 'lower' attribute";
1343 else if (has_attr (ATTR_UPPER
, * node
))
1344 message
= "already marked with 'upper' attribute";
1349 warning (OPT_Wattributes
, message
, name
);
1350 * no_add_attrs
= true;
1356 #undef TARGET_ATTRIBUTE_TABLE
1357 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1359 /* Table of MSP430-specific attributes. */
1360 const struct attribute_spec msp430_attribute_table
[] =
1362 /* Name min_num_args type_req, affects_type_identity
1363 max_num_args, fn_type_req
1364 decl_req handler. */
1365 { ATTR_INTR
, 0, 1, true, false, false, msp430_attr
, false },
1366 { ATTR_NAKED
, 0, 0, true, false, false, msp430_attr
, false },
1367 { ATTR_REENT
, 0, 0, true, false, false, msp430_attr
, false },
1368 { ATTR_CRIT
, 0, 0, true, false, false, msp430_attr
, false },
1369 { ATTR_WAKEUP
, 0, 0, true, false, false, msp430_attr
, false },
1371 { ATTR_LOWER
, 0, 0, true, false, false, msp430_section_attr
, false },
1372 { ATTR_UPPER
, 0, 0, true, false, false, msp430_section_attr
, false },
1373 { ATTR_EITHER
, 0, 0, true, false, false, msp430_section_attr
, false },
1375 { NULL
, 0, 0, false, false, false, NULL
, false }
1378 #undef TARGET_ASM_FUNCTION_PROLOGUE
1379 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1382 msp430_start_function (FILE *outfile
, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED
)
1386 fprintf (outfile
, "; start of function\n");
1388 if (DECL_ATTRIBUTES (current_function_decl
) != NULL_TREE
)
1390 fprintf (outfile
, "; attributes: ");
1391 if (is_naked_func ())
1392 fprintf (outfile
, "naked ");
1393 if (msp430_is_interrupt_func ())
1394 fprintf (outfile
, "interrupt ");
1395 if (is_reentrant_func ())
1396 fprintf (outfile
, "reentrant ");
1397 if (is_critical_func ())
1398 fprintf (outfile
, "critical ");
1399 if (is_wakeup_func ())
1400 fprintf (outfile
, "wakeup ");
1401 fprintf (outfile
, "\n");
1404 fprintf (outfile
, "; framesize_regs: %d\n", cfun
->machine
->framesize_regs
);
1405 fprintf (outfile
, "; framesize_locals: %d\n", cfun
->machine
->framesize_locals
);
1406 fprintf (outfile
, "; framesize_outgoing: %d\n", cfun
->machine
->framesize_outgoing
);
1407 fprintf (outfile
, "; framesize: %d\n", cfun
->machine
->framesize
);
1408 fprintf (outfile
, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM
, FRAME_POINTER_REGNUM
));
1409 fprintf (outfile
, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM
, STACK_POINTER_REGNUM
));
1412 fprintf (outfile
, "; saved regs:");
1413 for (r
= 0; r
< ARG_POINTER_REGNUM
; r
++)
1414 if (cfun
->machine
->need_to_save
[r
])
1416 fprintf (outfile
, " %s", reg_names
[r
]);
1420 fprintf (outfile
, "(none)");
1421 fprintf (outfile
, "\n");
1424 /* Common code to change the stack pointer. */
1426 increment_stack (HOST_WIDE_INT amount
)
1429 rtx sp
= stack_pointer_rtx
;
1436 inc
= GEN_INT (- amount
);
1438 F (emit_insn (gen_subpsi3 (sp
, sp
, inc
)));
1440 F (emit_insn (gen_subhi3 (sp
, sp
, inc
)));
1444 inc
= GEN_INT (amount
);
1446 emit_insn (gen_addpsi3 (sp
, sp
, inc
));
1448 emit_insn (gen_addhi3 (sp
, sp
, inc
));
1453 msp430_start_function (FILE *file
, const char *name
, tree decl
)
1457 int_attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
1458 if (int_attr
!= NULL_TREE
)
1460 tree intr_vector
= TREE_VALUE (int_attr
);
1462 if (intr_vector
!= NULL_TREE
)
1466 intr_vector
= TREE_VALUE (intr_vector
);
1468 /* The interrupt attribute has a vector value. Turn this into a
1469 section name, switch to that section and put the address of
1470 the current function into that vector slot. Note msp430_attr()
1471 has already verified the vector name for us. */
1472 if (TREE_CODE (intr_vector
) == STRING_CST
)
1473 sprintf (buf
, "__interrupt_vector_%.80s",
1474 TREE_STRING_POINTER (intr_vector
));
1475 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1476 sprintf (buf
, "__interrupt_vector_%u",
1477 (unsigned int) TREE_INT_CST_LOW (intr_vector
));
1479 switch_to_section (get_section (buf
, SECTION_CODE
, decl
));
1480 fputs ("\t.word\t", file
);
1481 assemble_name (file
, name
);
1487 switch_to_section (function_section (decl
));
1488 ASM_OUTPUT_FUNCTION_LABEL (file
, name
, decl
);
1491 static const char * const lower_prefix
= ".lower";
1492 static const char * const upper_prefix
= ".upper";
1493 static const char * const either_prefix
= ".either";
1495 /* Generate a prefix for a section name, based upon
1496 the region into which the object should be placed. */
1499 gen_prefix (tree decl
)
1501 if (DECL_ONE_ONLY (decl
))
1504 /* If the user has specified a particular section then do not use any prefix. */
1505 if (has_attr ("section", decl
))
1508 /* If the object has __attribute__((lower)) then use the ".lower." prefix. */
1509 if (has_attr (ATTR_LOWER
, decl
))
1510 return lower_prefix
;
1512 /* If we are compiling for the MSP430 then we do not support the upper region. */
1516 if (has_attr (ATTR_UPPER
, decl
))
1517 return upper_prefix
;
1519 if (has_attr (ATTR_EITHER
, decl
))
1520 return either_prefix
;
1522 if (TREE_CODE (decl
) == FUNCTION_DECL
)
1524 if (msp430_code_region
== LOWER
)
1525 return lower_prefix
;
1527 if (msp430_code_region
== UPPER
)
1528 return upper_prefix
;
1530 if (msp430_code_region
== EITHER
)
1531 return either_prefix
;
1535 if (msp430_data_region
== LOWER
)
1536 return lower_prefix
;
1538 if (msp430_data_region
== UPPER
)
1539 return upper_prefix
;
1541 if (msp430_data_region
== EITHER
)
1542 return either_prefix
;
1548 #undef TARGET_ASM_SELECT_SECTION
1549 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1552 msp430_select_section (tree decl
, int reloc
, unsigned HOST_WIDE_INT align
)
1554 gcc_assert (decl
!= NULL_TREE
);
1556 if (TREE_CODE (decl
) == STRING_CST
1557 || TREE_CODE (decl
) == CONSTRUCTOR
1558 || TREE_CODE (decl
) == INTEGER_CST
1559 || TREE_CODE (decl
) == VECTOR_CST
1560 || TREE_CODE (decl
) == COMPLEX_CST
)
1561 return default_select_section (decl
, reloc
, align
);
1563 /* In large mode we must make sure that interrupt handlers are put into
1564 low memory as the vector table only accepts 16-bit addresses. */
1565 if (TARGET_LARGE
&& TREE_CODE (decl
) == FUNCTION_DECL
&& is_interrupt_func (decl
))
1566 return get_section (".lowtext", SECTION_CODE
| SECTION_WRITE
, decl
);
1568 const char * prefix
= gen_prefix (decl
);
1571 if (TREE_CODE (decl
) == FUNCTION_DECL
)
1572 return text_section
;
1574 return default_select_section (decl
, reloc
, align
);
1578 switch (categorize_decl_for_section (decl
, reloc
))
1580 case SECCAT_TEXT
: sec
= ".text"; break;
1581 case SECCAT_DATA
: sec
= ".data"; break;
1582 case SECCAT_BSS
: sec
= ".bss"; break;
1583 case SECCAT_RODATA
: sec
= ".rodata"; break;
1585 case SECCAT_RODATA_MERGE_STR
:
1586 case SECCAT_RODATA_MERGE_STR_INIT
:
1587 case SECCAT_RODATA_MERGE_CONST
:
1588 case SECCAT_SRODATA
:
1589 case SECCAT_DATA_REL
:
1590 case SECCAT_DATA_REL_LOCAL
:
1591 case SECCAT_DATA_REL_RO
:
1592 case SECCAT_DATA_REL_RO_LOCAL
:
1597 return default_select_section (decl
, reloc
, align
);
1603 const char * dec_name
= DECL_SECTION_NAME (decl
);
1604 char * name
= ACONCAT ((prefix
, sec
, dec_name
, NULL
));
1606 return get_named_section (decl
, name
, 0);
1609 #undef TARGET_ASM_FUNCTION_SECTION
1610 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1613 msp430_function_section (tree decl
, enum node_frequency freq
, bool startup
, bool exit
)
1617 gcc_assert (DECL_SECTION_NAME (decl
) != NULL
);
1618 name
= DECL_SECTION_NAME (decl
);
1620 const char * prefix
= gen_prefix (decl
);
1622 || strncmp (name
, prefix
, strlen (prefix
)) == 0)
1623 return default_function_section (decl
, freq
, startup
, exit
);
1625 name
= ACONCAT ((prefix
, name
, NULL
));
1626 return get_named_section (decl
, name
, 0);
1629 #undef TARGET_SECTION_TYPE_FLAGS
1630 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1633 msp430_section_type_flags (tree decl
, const char * name
, int reloc
)
1635 if (strncmp (name
, lower_prefix
, strlen (lower_prefix
)) == 0)
1636 name
+= strlen (lower_prefix
);
1637 else if (strncmp (name
, upper_prefix
, strlen (upper_prefix
)) == 0)
1638 name
+= strlen (upper_prefix
);
1639 else if (strncmp (name
, either_prefix
, strlen (either_prefix
)) == 0)
1640 name
+= strlen (either_prefix
);
1642 return default_section_type_flags (decl
, name
, reloc
);
1645 #undef TARGET_ASM_UNIQUE_SECTION
1646 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1649 msp430_unique_section (tree decl
, int reloc
)
1651 gcc_assert (decl
!= NULL_TREE
);
1653 /* In large mode we must make sure that interrupt handlers are put into
1654 low memory as the vector table only accepts 16-bit addresses. */
1655 if (TARGET_LARGE
&& TREE_CODE (decl
) == FUNCTION_DECL
&& is_interrupt_func (decl
))
1657 set_decl_section_name (decl
, ".lowtext");
1661 default_unique_section (decl
, reloc
);
1663 const char * prefix
;
1665 if ( TREE_CODE (decl
) == STRING_CST
1666 || TREE_CODE (decl
) == CONSTRUCTOR
1667 || TREE_CODE (decl
) == INTEGER_CST
1668 || TREE_CODE (decl
) == VECTOR_CST
1669 || TREE_CODE (decl
) == COMPLEX_CST
1670 || (prefix
= gen_prefix (decl
)) == NULL
1674 const char * dec_name
= DECL_SECTION_NAME (decl
);
1675 char * name
= ACONCAT ((prefix
, dec_name
, NULL
));
1677 set_decl_section_name (decl
, name
);
1680 /* Emit a declaration of a common symbol.
1681 If a data region is in use then put the symbol into the
1682 equivalent .bss section instead. */
1685 msp430_output_aligned_decl_common (FILE * stream
,
1688 unsigned HOST_WIDE_INT size
,
1691 if (msp430_data_region
== ANY
)
1693 fprintf (stream
, COMMON_ASM_OP
);
1694 assemble_name (stream
, name
);
1695 fprintf (stream
, "," HOST_WIDE_INT_PRINT_UNSIGNED
",%u\n",
1696 size
, align
/ BITS_PER_UNIT
);
1703 sec
= msp430_select_section (decl
, 0, align
);
1705 switch (msp430_data_region
)
1707 case UPPER
: sec
= get_named_section (NULL
, ".upper.bss", 0); break;
1708 case LOWER
: sec
= get_named_section (NULL
, ".lower.bss", 0); break;
1709 case EITHER
: sec
= get_named_section (NULL
, ".either.bss", 0); break;
1713 gcc_assert (sec
!= NULL
);
1715 switch_to_section (sec
);
1716 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
1717 targetm
.asm_out
.globalize_label (stream
, name
);
1718 ASM_WEAKEN_LABEL (stream
, name
);
1719 ASM_OUTPUT_LABEL (stream
, name
);
1720 ASM_OUTPUT_SKIP (stream
, size
? size
: 1);
1725 msp430_do_not_relax_short_jumps (void)
1727 /* When placing code into "either" low or high memory we do not want the linker
1728 to grow the size of sections, which it can do if it is encounters a branch to
1729 a label that is too far away. So we tell the cbranch patterns to avoid using
1730 short jumps when there is a chance that the instructions will end up in a low
1733 msp430_code_region
== EITHER
1734 || msp430_code_region
== LOWER
1735 || has_attr (ATTR_EITHER
, current_function_decl
)
1736 || has_attr (ATTR_LOWER
, current_function_decl
);
1741 MSP430_BUILTIN_BIC_SR
,
1742 MSP430_BUILTIN_BIS_SR
,
1743 MSP430_BUILTIN_DELAY_CYCLES
,
1747 static GTY(()) tree msp430_builtins
[(int) MSP430_BUILTIN_max
];
1750 msp430_init_builtins (void)
1752 tree void_ftype_int
= build_function_type_list (void_type_node
, integer_type_node
, NULL
);
1753 tree void_ftype_longlong
= build_function_type_list (void_type_node
, long_long_integer_type_node
, NULL
);
1755 msp430_builtins
[MSP430_BUILTIN_BIC_SR
] =
1756 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int
,
1757 MSP430_BUILTIN_BIC_SR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1759 msp430_builtins
[MSP430_BUILTIN_BIS_SR
] =
1760 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int
,
1761 MSP430_BUILTIN_BIS_SR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1763 msp430_builtins
[MSP430_BUILTIN_DELAY_CYCLES
] =
1764 add_builtin_function ( "__delay_cycles", void_ftype_longlong
,
1765 MSP430_BUILTIN_DELAY_CYCLES
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1769 msp430_builtin_decl (unsigned code
, bool initialize ATTRIBUTE_UNUSED
)
1773 case MSP430_BUILTIN_BIC_SR
:
1774 case MSP430_BUILTIN_BIS_SR
:
1775 case MSP430_BUILTIN_DELAY_CYCLES
:
1776 return msp430_builtins
[code
];
1778 return error_mark_node
;
1782 /* These constants are really register reads, which are faster than
1783 regular constants. */
1785 cg_magic_constant (HOST_WIDE_INT c
)
1803 msp430_expand_delay_cycles (rtx arg
)
1805 HOST_WIDE_INT i
, c
, n
;
1806 /* extra cycles for MSP430X instructions */
1807 #define CYCX(M,X) (msp430x ? (X) : (M))
1809 if (GET_CODE (arg
) != CONST_INT
)
1811 error ("__delay_cycles() only takes constant arguments");
1817 if (HOST_BITS_PER_WIDE_INT
> 32)
1821 error ("__delay_cycles only takes non-negative cycle counts.");
1826 emit_insn (gen_delay_cycles_start (arg
));
1828 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
1829 if (c
> 3 * 0xffff + CYCX (7, 10))
1832 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long (x<=0xffff) loop */
1833 if (c
>= 0x10000 * 7 + CYCX (14, 16))
1836 c
-= CYCX (14, 16) + 7 * 0x10000;
1839 if ((unsigned long long) i
> 0xffffffffULL
)
1841 error ("__delay_cycles is limited to 32-bit loop counts.");
1847 i
= (c
- CYCX (14, 16)) / 7;
1848 c
-= CYCX (14, 16) + i
* 7;
1851 if (cg_magic_constant (i
& 0xffff))
1853 if (cg_magic_constant ((i
>> 16) & 0xffff))
1857 emit_insn (gen_delay_cycles_32x (GEN_INT (i
), GEN_INT (n
- c
)));
1859 emit_insn (gen_delay_cycles_32 (GEN_INT (i
), GEN_INT (n
- c
)));
1862 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */
1866 i
= (c
- CYCX (7, 10)) / 3;
1867 c
-= CYCX (7, 10) + i
* 3;
1869 if (cg_magic_constant (i
))
1873 emit_insn (gen_delay_cycles_16x (GEN_INT (i
), GEN_INT (n
- c
)));
1875 emit_insn (gen_delay_cycles_16 (GEN_INT (i
), GEN_INT (n
- c
)));
1880 emit_insn (gen_delay_cycles_2 ());
1886 emit_insn (gen_delay_cycles_1 ());
1890 emit_insn (gen_delay_cycles_end (arg
));
1896 msp430_expand_builtin (tree exp
,
1897 rtx target ATTRIBUTE_UNUSED
,
1898 rtx subtarget ATTRIBUTE_UNUSED
,
1899 machine_mode mode ATTRIBUTE_UNUSED
,
1900 int ignore ATTRIBUTE_UNUSED
)
1902 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
1903 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
1904 rtx arg1
= expand_normal (CALL_EXPR_ARG (exp
, 0));
1906 if (fcode
== MSP430_BUILTIN_DELAY_CYCLES
)
1907 return msp430_expand_delay_cycles (arg1
);
1909 if (! msp430_is_interrupt_func ())
1911 error ("MSP430 builtin functions only work inside interrupt handlers");
1915 if (! REG_P (arg1
) && ! CONSTANT_P (arg1
))
1916 arg1
= force_reg (mode
, arg1
);
1920 case MSP430_BUILTIN_BIC_SR
: emit_insn (gen_bic_SR (arg1
)); break;
1921 case MSP430_BUILTIN_BIS_SR
: emit_insn (gen_bis_SR (arg1
)); break;
1923 internal_error ("bad builtin code");
1929 #undef TARGET_INIT_BUILTINS
1930 #define TARGET_INIT_BUILTINS msp430_init_builtins
1932 #undef TARGET_EXPAND_BUILTIN
1933 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
1935 #undef TARGET_BUILTIN_DECL
1936 #define TARGET_BUILTIN_DECL msp430_builtin_decl
1939 msp430_expand_prologue (void)
1943 /* Always use stack_pointer_rtx instead of calling
1944 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
1945 that there is a single rtx representing the stack pointer,
1946 namely stack_pointer_rtx, and uses == to recognize it. */
1947 rtx sp
= stack_pointer_rtx
;
1950 if (is_naked_func ())
1952 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
1953 examines the output of the gen_prologue() function. */
1954 emit_insn (gen_rtx_CLOBBER (VOIDmode
, GEN_INT (0)));
1958 emit_insn (gen_prologue_start_marker ());
1960 if (is_critical_func ())
1962 emit_insn (gen_push_intr_state ());
1963 emit_insn (gen_disable_interrupts ());
1965 else if (is_reentrant_func ())
1966 emit_insn (gen_disable_interrupts ());
1968 if (!cfun
->machine
->computed
)
1969 msp430_compute_frame_info ();
1971 if (flag_stack_usage_info
)
1972 current_function_static_stack_size
= cfun
->machine
->framesize
;
1974 if (crtl
->args
.pretend_args_size
)
1978 gcc_assert (crtl
->args
.pretend_args_size
== 2);
1980 p
= emit_insn (gen_grow_and_swap ());
1982 /* Document the stack decrement... */
1983 note
= F (gen_rtx_SET (stack_pointer_rtx
,
1984 gen_rtx_MINUS (Pmode
, stack_pointer_rtx
, GEN_INT (2))));
1985 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
1987 /* ...and the establishment of a new location for the return address. */
1988 note
= F (gen_rtx_SET (gen_rtx_MEM (Pmode
,
1989 gen_rtx_PLUS (Pmode
,
1993 add_reg_note (p
, REG_CFA_OFFSET
, note
);
1997 for (i
= 15; i
>= 4; i
--)
1998 if (cfun
->machine
->need_to_save
[i
])
2003 for (seq
= i
- 1; seq
>= 4 && cfun
->machine
->need_to_save
[seq
]; seq
--)
2009 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */
2010 p
= F (emit_insn (gen_pushm (gen_rtx_REG (Pmode
, i
),
2013 note
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (count
+ 1));
2015 XVECEXP (note
, 0, 0)
2016 = F (gen_rtx_SET (stack_pointer_rtx
,
2017 gen_rtx_PLUS (Pmode
,
2019 GEN_INT (count
* (TARGET_LARGE
? -4 : -2)))));
2021 /* *sp-- = R[i-j] */
2025 for (j
= 0; j
< count
; j
++)
2028 int ofs
= (count
- j
- 1) * (TARGET_LARGE
? 4 : 2);
2031 addr
= gen_rtx_PLUS (Pmode
, sp
, GEN_INT (ofs
));
2033 addr
= stack_pointer_rtx
;
2035 XVECEXP (note
, 0, j
+ 1) =
2036 F (gen_rtx_SET (gen_rtx_MEM (Pmode
, addr
),
2037 gen_rtx_REG (Pmode
, i
- j
)) );
2040 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
2044 F (emit_insn (gen_push (gen_rtx_REG (Pmode
, i
))));
2047 if (frame_pointer_needed
)
2048 F (emit_move_insn (gen_rtx_REG (Pmode
, FRAME_POINTER_REGNUM
), sp
));
2050 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
2052 increment_stack (- fs
);
2054 emit_insn (gen_prologue_end_marker ());
2058 msp430_expand_epilogue (int is_eh
)
2064 if (is_naked_func ())
2066 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2067 examines the output of the gen_epilogue() function. */
2068 emit_insn (gen_rtx_CLOBBER (VOIDmode
, GEN_INT (0)));
2072 if (cfun
->machine
->need_to_save
[10])
2074 /* Check for a helper function. */
2075 helper_n
= 7; /* For when the loop below never sees a match. */
2076 for (i
= 9; i
>= 4; i
--)
2077 if (!cfun
->machine
->need_to_save
[i
])
2081 if (cfun
->machine
->need_to_save
[i
])
2090 emit_insn (gen_epilogue_start_marker ());
2092 if (cfun
->decl
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun
->decl
)), "main") == 0)
2093 emit_insn (gen_msp430_refsym_need_exit ());
2095 if (is_wakeup_func ())
2096 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2097 status register current residing on the stack. When this function
2098 executes its RETI instruction the SR will be updated with this saved
2099 value, thus ensuring that the processor is woken up from any low power
2100 state in which it may be residing. */
2101 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2103 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
2105 increment_stack (fs
);
2109 /* We need to add the right "SP" register save just after the
2110 regular ones, so that when we pop it off we're in the EH
2111 return frame, not this one. This overwrites our own return
2112 address, but we're not going to be returning anyway. */
2113 rtx r12
= gen_rtx_REG (Pmode
, 12);
2114 rtx (*addPmode
)(rtx
, rtx
, rtx
) = TARGET_LARGE
? gen_addpsi3
: gen_addhi3
;
2116 /* R12 will hold the new SP. */
2117 i
= cfun
->machine
->framesize_regs
;
2118 emit_move_insn (r12
, stack_pointer_rtx
);
2119 emit_insn (addPmode (r12
, r12
, EH_RETURN_STACKADJ_RTX
));
2120 emit_insn (addPmode (r12
, r12
, GEN_INT (i
)));
2121 emit_move_insn (gen_rtx_MEM (Pmode
, plus_constant (Pmode
, stack_pointer_rtx
, i
)), r12
);
2124 for (i
= 4; i
<= 15; i
++)
2125 if (cfun
->machine
->need_to_save
[i
])
2129 for (seq
= i
+ 1; seq
<= 15 && cfun
->machine
->need_to_save
[seq
]; seq
++)
2135 /* Note: With TARGET_LARGE we still use
2136 POPM as POPX.A is two bytes bigger. */
2137 emit_insn (gen_popm (stack_pointer_rtx
, GEN_INT (seq
- 1),
2141 else if (i
== 11 - helper_n
2142 && ! msp430_is_interrupt_func ()
2143 && ! is_reentrant_func ()
2144 && ! is_critical_func ()
2145 && crtl
->args
.pretend_args_size
== 0
2146 /* Calling the helper takes as many bytes as the POP;RET sequence. */
2150 emit_insn (gen_epilogue_helper (GEN_INT (helper_n
)));
2154 emit_insn (gen_pop (gen_rtx_REG (Pmode
, i
)));
2159 /* Also pop SP, which puts us into the EH return frame. Except
2160 that you can't "pop" sp, you have to just load it off the
2162 emit_move_insn (stack_pointer_rtx
, gen_rtx_MEM (Pmode
, stack_pointer_rtx
));
2165 if (crtl
->args
.pretend_args_size
)
2166 emit_insn (gen_swap_and_shrink ());
2168 if (is_critical_func ())
2169 emit_insn (gen_pop_intr_state ());
2170 else if (is_reentrant_func ())
2171 emit_insn (gen_enable_interrupts ());
2173 emit_jump_insn (gen_msp_return ());
2176 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2177 m32c_emit_eh_epilogue. */
2179 msp430_eh_return_stackadj_rtx (void)
2181 if (!cfun
->machine
->eh_stack_adjust
)
2185 sa
= gen_rtx_REG (Pmode
, 15);
2186 cfun
->machine
->eh_stack_adjust
= sa
;
2188 return cfun
->machine
->eh_stack_adjust
;
2191 /* This function is called before reload, to "fix" the stack in
2192 preparation for an EH return. */
2194 msp430_expand_eh_return (rtx eh_handler
)
2196 /* These are all Pmode */
2197 rtx ap
, sa
, ra
, tmp
;
2199 ap
= arg_pointer_rtx
;
2200 sa
= msp430_eh_return_stackadj_rtx ();
2204 tmp
= gen_rtx_PLUS (Pmode
, ap
, sa
);
2205 tmp
= plus_constant (Pmode
, tmp
, TARGET_LARGE
? -4 : -2);
2206 tmp
= gen_rtx_MEM (Pmode
, tmp
);
2207 emit_move_insn (tmp
, ra
);
2210 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
2211 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2213 msp430_init_dwarf_reg_sizes_extra (tree address
)
2216 rtx addr
= expand_normal (address
);
2217 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
2222 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2224 unsigned int dnum
= DWARF_FRAME_REGNUM (i
);
2225 unsigned int rnum
= DWARF2_FRAME_REG_OUT (dnum
, 1);
2227 if (rnum
< DWARF_FRAME_REGISTERS
)
2229 HOST_WIDE_INT offset
= rnum
* GET_MODE_SIZE (QImode
);
2231 emit_move_insn (adjust_address (mem
, QImode
, offset
),
2232 gen_int_mode (4, QImode
));
2237 /* This is a list of MD patterns that implement fixed-count shifts. */
2243 rtx (*genfunc
)(rtx
,rtx
);
2245 const_shift_helpers
[] =
2247 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2249 CSH ("slli", 1, 1, slli_1
),
2250 CSH ("slll", 1, 1, slll_1
),
2251 CSH ("slll", 2, 1, slll_2
),
2253 CSH ("srai", 1, 0, srai_1
),
2254 CSH ("sral", 1, 0, sral_1
),
2255 CSH ("sral", 2, 0, sral_2
),
2257 CSH ("srll", 1, 0, srll_1
),
2258 CSH ("srll", 2, 1, srll_2x
),
2263 /* The MSP430 ABI defines a number of helper functions that should be
2264 used for, for example, 32-bit shifts. This function is called to
2265 emit such a function, using the table above to optimize some
2268 msp430_expand_helper (rtx
*operands
, const char *helper_name
, bool const_variants
)
2271 char *helper_const
= NULL
;
2274 machine_mode arg0mode
= GET_MODE (operands
[0]);
2275 machine_mode arg1mode
= GET_MODE (operands
[1]);
2276 machine_mode arg2mode
= GET_MODE (operands
[2]);
2277 int have_430x
= msp430x
? 1 : 0;
2279 if (CONST_INT_P (operands
[2]))
2283 for (i
=0; const_shift_helpers
[i
].name
; i
++)
2285 if (const_shift_helpers
[i
].need_430x
<= have_430x
2286 && strcmp (helper_name
, const_shift_helpers
[i
].name
) == 0
2287 && INTVAL (operands
[2]) == const_shift_helpers
[i
].count
)
2289 emit_insn (const_shift_helpers
[i
].genfunc (operands
[0], operands
[1]));
2295 if (arg1mode
== VOIDmode
)
2296 arg1mode
= arg0mode
;
2297 if (arg2mode
== VOIDmode
)
2298 arg2mode
= arg0mode
;
2300 if (arg1mode
== SImode
)
2307 && CONST_INT_P (operands
[2])
2308 && INTVAL (operands
[2]) >= 1
2309 && INTVAL (operands
[2]) <= 15)
2311 /* Note that the INTVAL is limited in value and length by the conditional above. */
2312 int len
= strlen (helper_name
) + 4;
2313 helper_const
= (char *) xmalloc (len
);
2314 snprintf (helper_const
, len
, "%s_%d", helper_name
, (int) INTVAL (operands
[2]));
2317 emit_move_insn (gen_rtx_REG (arg1mode
, 12),
2320 emit_move_insn (gen_rtx_REG (arg2mode
, arg2
),
2323 c
= gen_call_value_internal (gen_rtx_REG (arg0mode
, 12),
2324 gen_rtx_SYMBOL_REF (VOIDmode
, helper_const
? helper_const
: helper_name
),
2326 c
= emit_call_insn (c
);
2327 RTL_CONST_CALL_P (c
) = 1;
2330 use_regs (&f
, 12, arg1sz
);
2332 use_regs (&f
, arg2
, 1);
2333 add_function_usage_to (c
, f
);
2335 emit_move_insn (operands
[0],
2336 gen_rtx_REG (arg0mode
, 12));
2339 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
2341 msp430_fixup_compare_operands (machine_mode my_mode
, rtx
* operands
)
2343 /* constants we're looking for, not constants which are allowed. */
2344 int const_op_idx
= 1;
2346 if (msp430_reversible_cmp_operator (operands
[0], VOIDmode
))
2349 if (GET_CODE (operands
[const_op_idx
]) != REG
2350 && GET_CODE (operands
[const_op_idx
]) != MEM
)
2351 operands
[const_op_idx
] = copy_to_mode_reg (my_mode
, operands
[const_op_idx
]);
2354 /* Simplify_gen_subreg() doesn't handle memory references the way we
2355 need it to below, so we use this function for when we must get a
2356 valid subreg in a "natural" state. */
2358 msp430_subreg (machine_mode mode
, rtx r
, machine_mode omode
, int byte
)
2362 if (GET_CODE (r
) == SUBREG
2363 && SUBREG_BYTE (r
) == 0)
2365 rtx ireg
= SUBREG_REG (r
);
2366 machine_mode imode
= GET_MODE (ireg
);
2368 /* special case for (HI (SI (PSI ...), 0)) */
2369 if (imode
== PSImode
2372 rv
= gen_rtx_SUBREG (mode
, ireg
, byte
);
2374 rv
= simplify_gen_subreg (mode
, ireg
, imode
, byte
);
2376 else if (GET_CODE (r
) == MEM
)
2377 rv
= adjust_address (r
, mode
, byte
);
2378 else if (GET_CODE (r
) == SYMBOL_REF
2379 && (byte
== 0 || byte
== 2)
2382 rv
= gen_rtx_ZERO_EXTRACT (HImode
, r
, GEN_INT (16), GEN_INT (8*byte
));
2383 rv
= gen_rtx_CONST (HImode
, r
);
2386 rv
= simplify_gen_subreg (mode
, r
, omode
, byte
);
2394 /* Called by movsi_x to generate the HImode operands. */
2396 msp430_split_movsi (rtx
*operands
)
2398 rtx op00
, op02
, op10
, op12
;
2400 op00
= msp430_subreg (HImode
, operands
[0], SImode
, 0);
2401 op02
= msp430_subreg (HImode
, operands
[0], SImode
, 2);
2403 if (GET_CODE (operands
[1]) == CONST
2404 || GET_CODE (operands
[1]) == SYMBOL_REF
)
2406 op10
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (0));
2407 op10
= gen_rtx_CONST (HImode
, op10
);
2408 op12
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (16));
2409 op12
= gen_rtx_CONST (HImode
, op12
);
2413 op10
= msp430_subreg (HImode
, operands
[1], SImode
, 0);
2414 op12
= msp430_subreg (HImode
, operands
[1], SImode
, 2);
2417 if (rtx_equal_p (operands
[0], operands
[1]))
2424 else if (rtx_equal_p (op00
, op12
)
2425 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
2426 || (REG_P (op00
) && reg_mentioned_p (op00
, op10
))
2427 /* Or storing (rN) into mem (rN). */
2428 || (REG_P (op10
) && reg_mentioned_p (op10
, op00
))
2446 /* The MSPABI specifies the names of various helper functions, many of
2447 which are compatible with GCC's helpers. This table maps the GCC
2448 name to the MSPABI name. */
2451 char const * const gcc_name
;
2452 char const * const ti_name
;
2454 helper_function_name_mappings
[] =
2456 /* Floating point to/from integer conversions. */
2457 { "__truncdfsf2", "__mspabi_cvtdf" },
2458 { "__extendsfdf2", "__mspabi_cvtfd" },
2459 { "__fixdfhi", "__mspabi_fixdi" },
2460 { "__fixdfsi", "__mspabi_fixdli" },
2461 { "__fixdfdi", "__mspabi_fixdlli" },
2462 { "__fixunsdfhi", "__mspabi_fixdu" },
2463 { "__fixunsdfsi", "__mspabi_fixdul" },
2464 { "__fixunsdfdi", "__mspabi_fixdull" },
2465 { "__fixsfhi", "__mspabi_fixfi" },
2466 { "__fixsfsi", "__mspabi_fixfli" },
2467 { "__fixsfdi", "__mspabi_fixflli" },
2468 { "__fixunsfhi", "__mspabi_fixfu" },
2469 { "__fixunsfsi", "__mspabi_fixful" },
2470 { "__fixunsfdi", "__mspabi_fixfull" },
2471 { "__floathisf", "__mspabi_fltif" },
2472 { "__floatsisf", "__mspabi_fltlif" },
2473 { "__floatdisf", "__mspabi_fltllif" },
2474 { "__floathidf", "__mspabi_fltid" },
2475 { "__floatsidf", "__mspabi_fltlid" },
2476 { "__floatdidf", "__mspabi_fltllid" },
2477 { "__floatunhisf", "__mspabi_fltuf" },
2478 { "__floatunsisf", "__mspabi_fltulf" },
2479 { "__floatundisf", "__mspabi_fltullf" },
2480 { "__floatunhidf", "__mspabi_fltud" },
2481 { "__floatunsidf", "__mspabi_fltuld" },
2482 { "__floatundidf", "__mspabi_fltulld" },
2484 /* Floating point comparisons. */
2485 /* GCC uses individual functions for each comparison, TI uses one
2486 compare <=> function. */
2488 /* Floating point arithmatic */
2489 { "__adddf3", "__mspabi_addd" },
2490 { "__addsf3", "__mspabi_addf" },
2491 { "__divdf3", "__mspabi_divd" },
2492 { "__divsf3", "__mspabi_divf" },
2493 { "__muldf3", "__mspabi_mpyd" },
2494 { "__mulsf3", "__mspabi_mpyf" },
2495 { "__subdf3", "__mspabi_subd" },
2496 { "__subsf3", "__mspabi_subf" },
2497 /* GCC does not use helper functions for negation */
2499 /* Integer multiply, divide, remainder. */
2500 { "__mulhi3", "__mspabi_mpyi" },
2501 { "__mulsi3", "__mspabi_mpyl" },
2502 { "__muldi3", "__mspabi_mpyll" },
2504 /* Clarify signed vs unsigned first. */
2505 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */
2506 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */
2509 { "__divhi3", "__mspabi_divi" },
2510 { "__divsi3", "__mspabi_divli" },
2511 { "__divdi3", "__mspabi_divlli" },
2512 { "__udivhi3", "__mspabi_divu" },
2513 { "__udivsi3", "__mspabi_divlu" },
2514 { "__udivdi3", "__mspabi_divllu" },
2515 { "__modhi3", "__mspabi_remi" },
2516 { "__modsi3", "__mspabi_remli" },
2517 { "__moddi3", "__mspabi_remlli" },
2518 { "__umodhi3", "__mspabi_remu" },
2519 { "__umodsi3", "__mspabi_remul" },
2520 { "__umoddi3", "__mspabi_remull" },
2522 /* Bitwise operations. */
2523 /* Rotation - no rotation support yet. */
2524 /* Logical left shift - gcc already does these itself. */
2525 /* Arithmetic left shift - gcc already does these itself. */
2526 /* Arithmetic right shift - gcc already does these itself. */
2531 /* Returns true if the current MCU supports an F5xxx series
2532 hardware multiper. */
2535 msp430_use_f5_series_hwmult (void)
2537 static const char * cached_match
= NULL
;
2538 static bool cached_result
;
2540 if (msp430_hwmult_type
== F5SERIES
)
2543 if (target_mcu
== NULL
|| msp430_hwmult_type
!= AUTO
)
2546 if (target_mcu
== cached_match
)
2547 return cached_result
;
2549 cached_match
= target_mcu
;
2551 if (strncasecmp (target_mcu
, "msp430f5", 8) == 0)
2552 return cached_result
= true;
2553 if (strncasecmp (target_mcu
, "msp430fr5", 9) == 0)
2554 return cached_result
= true;
2555 if (strncasecmp (target_mcu
, "msp430f6", 8) == 0)
2556 return cached_result
= true;
2558 static const char * known_f5_mult_mcus
[] =
2560 "cc430f5123", "cc430f5125", "cc430f5133",
2561 "cc430f5135", "cc430f5137", "cc430f5143",
2562 "cc430f5145", "cc430f5147", "cc430f6125",
2563 "cc430f6126", "cc430f6127", "cc430f6135",
2564 "cc430f6137", "cc430f6143", "cc430f6145",
2565 "cc430f6147", "msp430bt5190", "msp430sl5438a",
2570 for (i
= ARRAY_SIZE (known_f5_mult_mcus
); i
--;)
2571 if (strcasecmp (target_mcu
, known_f5_mult_mcus
[i
]) == 0)
2572 return cached_result
= true;
2574 return cached_result
= false;
2577 /* Returns true if the current MCU has a second generation
2578 32-bit hardware multiplier. */
2581 use_32bit_hwmult (void)
2583 static const char * known_32bit_mult_mcus
[] =
2585 "msp430f4783", "msp430f4793", "msp430f4784",
2586 "msp430f4794", "msp430f47126", "msp430f47127",
2587 "msp430f47163", "msp430f47173", "msp430f47183",
2588 "msp430f47193", "msp430f47166", "msp430f47176",
2589 "msp430f47186", "msp430f47196", "msp430f47167",
2590 "msp430f47177", "msp430f47187", "msp430f47197"
2592 static const char * cached_match
= NULL
;
2593 static bool cached_result
;
2596 if (msp430_hwmult_type
== LARGE
)
2599 if (target_mcu
== NULL
|| msp430_hwmult_type
!= AUTO
)
2602 if (target_mcu
== cached_match
)
2603 return cached_result
;
2605 cached_match
= target_mcu
;
2606 for (i
= ARRAY_SIZE (known_32bit_mult_mcus
); i
--;)
2607 if (strcasecmp (target_mcu
, known_32bit_mult_mcus
[i
]) == 0)
2608 return cached_result
= true;
2610 return cached_result
= false;
2613 /* Returns true if the current MCU does not have a
2614 hardware multiplier of any kind. */
2617 msp430_no_hwmult (void)
2619 static const char * known_nomult_mcus
[] =
2621 "msp430c091", "msp430c092", "msp430c111",
2622 "msp430c1111", "msp430c112", "msp430c1121",
2623 "msp430c1331", "msp430c1351", "msp430c311s",
2624 "msp430c312", "msp430c313", "msp430c314",
2625 "msp430c315", "msp430c323", "msp430c325",
2626 "msp430c412", "msp430c413", "msp430e112",
2627 "msp430e313", "msp430e315", "msp430e325",
2628 "msp430f110", "msp430f1101", "msp430f1101a",
2629 "msp430f1111", "msp430f1111a", "msp430f112",
2630 "msp430f1121", "msp430f1121a", "msp430f1122",
2631 "msp430f1132", "msp430f122", "msp430f1222",
2632 "msp430f123", "msp430f1232", "msp430f133",
2633 "msp430f135", "msp430f155", "msp430f156",
2634 "msp430f157", "msp430f2001", "msp430f2002",
2635 "msp430f2003", "msp430f2011", "msp430f2012",
2636 "msp430f2013", "msp430f2101", "msp430f2111",
2637 "msp430f2112", "msp430f2121", "msp430f2122",
2638 "msp430f2131", "msp430f2132", "msp430f2232",
2639 "msp430f2234", "msp430f2252", "msp430f2254",
2640 "msp430f2272", "msp430f2274", "msp430f412",
2641 "msp430f413", "msp430f4132", "msp430f415",
2642 "msp430f4152", "msp430f417", "msp430f4250",
2643 "msp430f4260", "msp430f4270", "msp430f435",
2644 "msp430f4351", "msp430f436", "msp430f4361",
2645 "msp430f437", "msp430f4371", "msp430f438",
2646 "msp430f439", "msp430f477", "msp430f478",
2647 "msp430f479", "msp430fe423", "msp430fe4232",
2648 "msp430fe423a", "msp430fe4242", "msp430fe425",
2649 "msp430fe4252", "msp430fe425a", "msp430fe427",
2650 "msp430fe4272", "msp430fe427a", "msp430fg4250",
2651 "msp430fg4260", "msp430fg4270", "msp430fg437",
2652 "msp430fg438", "msp430fg439", "msp430fg477",
2653 "msp430fg478", "msp430fg479", "msp430fr2032",
2654 "msp430fr2033", "msp430fr4131", "msp430fr4132",
2655 "msp430fr4133", "msp430fw423", "msp430fw425",
2656 "msp430fw427", "msp430fw428", "msp430fw429",
2657 "msp430g2001", "msp430g2101", "msp430g2102",
2658 "msp430g2111", "msp430g2112", "msp430g2113",
2659 "msp430g2121", "msp430g2131", "msp430g2132",
2660 "msp430g2152", "msp430g2153", "msp430g2201",
2661 "msp430g2202", "msp430g2203", "msp430g2210",
2662 "msp430g2211", "msp430g2212", "msp430g2213",
2663 "msp430g2221", "msp430g2230", "msp430g2231",
2664 "msp430g2232", "msp430g2233", "msp430g2252",
2665 "msp430g2253", "msp430g2302", "msp430g2303",
2666 "msp430g2312", "msp430g2313", "msp430g2332",
2667 "msp430g2333", "msp430g2352", "msp430g2353",
2668 "msp430g2402", "msp430g2403", "msp430g2412",
2669 "msp430g2413", "msp430g2432", "msp430g2433",
2670 "msp430g2444", "msp430g2452", "msp430g2453",
2671 "msp430g2513", "msp430g2533", "msp430g2544",
2672 "msp430g2553", "msp430g2744", "msp430g2755",
2673 "msp430g2855", "msp430g2955", "msp430l092",
2674 "msp430p112", "msp430p313", "msp430p315",
2675 "msp430p315s", "msp430p325", "msp430tch5e"
2677 static const char * cached_match
= NULL
;
2678 static bool cached_result
;
2681 if (msp430_hwmult_type
== NONE
)
2684 if (target_mcu
== NULL
|| msp430_hwmult_type
!= AUTO
)
2687 if (target_mcu
== cached_match
)
2688 return cached_result
;
2690 cached_match
= target_mcu
;
2691 for (i
= ARRAY_SIZE (known_nomult_mcus
); i
--;)
2692 if (strcasecmp (target_mcu
, known_nomult_mcus
[i
]) == 0)
2693 return cached_result
= true;
2695 return cached_result
= false;
2698 /* This function does the same as the default, but it will replace GCC
2699 function names with the MSPABI-specified ones. */
2702 msp430_output_labelref (FILE *file
, const char *name
)
2706 for (i
= 0; helper_function_name_mappings
[i
].gcc_name
; i
++)
2707 if (strcmp (helper_function_name_mappings
[i
].gcc_name
, name
) == 0)
2709 name
= helper_function_name_mappings
[i
].ti_name
;
2713 /* If we have been given a specific MCU name then we may be
2714 able to make use of its hardware multiply capabilities. */
2715 if (msp430_hwmult_type
!= NONE
)
2717 if (strcmp ("__mspabi_mpyi", name
) == 0)
2719 if (msp430_use_f5_series_hwmult ())
2720 name
= "__mulhi2_f5";
2721 else if (! msp430_no_hwmult ())
2724 else if (strcmp ("__mspabi_mpyl", name
) == 0)
2726 if (msp430_use_f5_series_hwmult ())
2727 name
= "__mulsi2_f5";
2728 else if (use_32bit_hwmult ())
2729 name
= "__mulsi2_hw32";
2730 else if (! msp430_no_hwmult ())
2738 /* Common code for msp430_print_operand... */
2741 msp430_print_operand_raw (FILE * file
, rtx op
)
2745 switch (GET_CODE (op
))
2748 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
2754 fprintf (file
, "%#" HOST_WIDE_INT_PRINT
"x", i
);
2756 fprintf (file
, "%" HOST_WIDE_INT_PRINT
"d", i
);
2764 output_addr_const (file
, op
);
2768 print_rtl (file
, op
);
2773 #undef TARGET_PRINT_OPERAND_ADDRESS
2774 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
2776 /* Output to stdio stream FILE the assembler syntax for an
2777 instruction operand that is a memory reference whose address
2781 msp430_print_operand_addr (FILE * file
, rtx addr
)
2783 switch (GET_CODE (addr
))
2786 msp430_print_operand_raw (file
, XEXP (addr
, 1));
2787 gcc_assert (REG_P (XEXP (addr
, 0)));
2788 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2792 fprintf (file
, "@");
2799 fprintf (file
, "&");
2806 msp430_print_operand_raw (file
, addr
);
2809 #undef TARGET_PRINT_OPERAND
2810 #define TARGET_PRINT_OPERAND msp430_print_operand
2812 /* A low 16-bits of int/lower of register pair
2813 B high 16-bits of int/higher of register pair
2814 C bits 32-47 of a 64-bit value/reg 3 of a DImode value
2815 D bits 48-63 of a 64-bit value/reg 4 of a DImode value
2816 H like %B (for backwards compatibility)
2818 J an integer without a # prefix
2819 L like %A (for backwards compatibility)
2820 O offset of the top of the stack
2821 Q like X but generates an A postfix
2822 R inverse of condition code, unsigned.
2823 X X instruction postfix in large mode
2826 b .B or .W or .A, depending upon the mode
2828 r inverse of condition code
2829 x like X but only for pointers. */
2832 msp430_print_operand (FILE * file
, rtx op
, int letter
)
2836 /* We can't use c, n, a, or l. */
2840 gcc_assert (CONST_INT_P (op
));
2841 /* Print the constant value, less one. */
2842 fprintf (file
, "#%ld", INTVAL (op
) - 1);
2845 gcc_assert (CONST_INT_P (op
));
2846 /* Print the constant value, less four. */
2847 fprintf (file
, "#%ld", INTVAL (op
) - 4);
2850 if (GET_CODE (op
) == CONST_INT
)
2852 /* Inverse of constants */
2853 int i
= INTVAL (op
);
2854 fprintf (file
, "%d", ~i
);
2859 case 'r': /* Conditional jump where the condition is reversed. */
2860 switch (GET_CODE (op
))
2862 case EQ
: fprintf (file
, "NE"); break;
2863 case NE
: fprintf (file
, "EQ"); break;
2864 case GEU
: fprintf (file
, "LO"); break;
2865 case LTU
: fprintf (file
, "HS"); break;
2866 case GE
: fprintf (file
, "L"); break;
2867 case LT
: fprintf (file
, "GE"); break;
2868 /* Assume these have reversed operands. */
2869 case GTU
: fprintf (file
, "HS"); break;
2870 case LEU
: fprintf (file
, "LO"); break;
2871 case GT
: fprintf (file
, "GE"); break;
2872 case LE
: fprintf (file
, "L"); break;
2874 msp430_print_operand_raw (file
, op
);
2878 case 'R': /* Conditional jump where the operands are reversed. */
2879 switch (GET_CODE (op
))
2881 case GTU
: fprintf (file
, "LO"); break;
2882 case LEU
: fprintf (file
, "HS"); break;
2883 case GT
: fprintf (file
, "L"); break;
2884 case LE
: fprintf (file
, "GE"); break;
2886 msp430_print_operand_raw (file
, op
);
2890 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
2891 gcc_assert (CONST_INT_P (op
));
2892 fprintf (file
, "#%d", 1 << INTVAL (op
));
2895 switch (GET_MODE (op
))
2897 case QImode
: fprintf (file
, ".B"); return;
2898 case HImode
: fprintf (file
, ".W"); return;
2899 case PSImode
: fprintf (file
, ".A"); return;
2900 case SImode
: fprintf (file
, ".A"); return;
2905 case 'L': /* Low half. */
2906 switch (GET_CODE (op
))
2909 op
= adjust_address (op
, Pmode
, 0);
2914 op
= GEN_INT (INTVAL (op
) & 0xffff);
2918 /* If you get here, figure out a test case :-) */
2923 case 'H': /* high half */
2924 switch (GET_CODE (op
))
2927 op
= adjust_address (op
, Pmode
, 2);
2930 op
= gen_rtx_REG (Pmode
, REGNO (op
) + 1);
2933 op
= GEN_INT (INTVAL (op
) >> 16);
2937 /* If you get here, figure out a test case :-) */
2942 switch (GET_CODE (op
))
2945 op
= adjust_address (op
, Pmode
, 3);
2948 op
= gen_rtx_REG (Pmode
, REGNO (op
) + 2);
2951 op
= GEN_INT ((long long) INTVAL (op
) >> 32);
2955 /* If you get here, figure out a test case :-) */
2960 switch (GET_CODE (op
))
2963 op
= adjust_address (op
, Pmode
, 4);
2966 op
= gen_rtx_REG (Pmode
, REGNO (op
) + 3);
2969 op
= GEN_INT ((long long) INTVAL (op
) >> 48);
2973 /* If you get here, figure out a test case :-) */
2979 /* This is used to turn, for example, an ADD opcode into an ADDX
2980 opcode when we're using 20-bit addresses. */
2981 if (TARGET_LARGE
|| GET_MODE (op
) == PSImode
)
2982 fprintf (file
, "X");
2983 /* We don't care which operand we use, but we want 'X' in the MD
2984 file, so we do it this way. */
2988 /* Similarly, but only for PSImodes. BIC, for example, needs this. */
2989 if (GET_MODE (op
) == PSImode
)
2990 fprintf (file
, "X");
2994 /* Likewise, for BR -> BRA. */
2996 fprintf (file
, "A");
3000 /* Computes the offset to the top of the stack for the current frame.
3001 This has to be done here rather than in, say, msp430_expand_builtin()
3002 because builtins are expanded before the frame layout is determined. */
3003 fprintf (file
, "%d",
3004 msp430_initial_elimination_offset (ARG_POINTER_REGNUM
, STACK_POINTER_REGNUM
)
3005 - (TARGET_LARGE
? 4 : 2));
3009 gcc_assert (GET_CODE (op
) == CONST_INT
);
3013 output_operand_lossage ("invalid operand prefix");
3017 switch (GET_CODE (op
))
3020 msp430_print_operand_raw (file
, op
);
3024 addr
= XEXP (op
, 0);
3025 msp430_print_operand_addr (file
, addr
);
3029 if (GET_CODE (XEXP (op
, 0)) == ZERO_EXTRACT
)
3032 switch (INTVAL (XEXP (op
, 2)))
3035 fprintf (file
, "#lo (");
3036 msp430_print_operand_raw (file
, XEXP (op
, 0));
3037 fprintf (file
, ")");
3041 fprintf (file
, "#hi (");
3042 msp430_print_operand_raw (file
, XEXP (op
, 0));
3043 fprintf (file
, ")");
3047 output_operand_lossage ("invalid zero extract");
3057 fprintf (file
, "#");
3058 msp430_print_operand_raw (file
, op
);
3061 case EQ
: fprintf (file
, "EQ"); break;
3062 case NE
: fprintf (file
, "NE"); break;
3063 case GEU
: fprintf (file
, "HS"); break;
3064 case LTU
: fprintf (file
, "LO"); break;
3065 case GE
: fprintf (file
, "GE"); break;
3066 case LT
: fprintf (file
, "L"); break;
3069 print_rtl (file
, op
);
3078 msp430_return_addr_rtx (int count
)
3084 ra_size
= TARGET_LARGE
? 4 : 2;
3085 if (crtl
->args
.pretend_args_size
)
3088 return gen_rtx_MEM (Pmode
, gen_rtx_PLUS (Pmode
, arg_pointer_rtx
, GEN_INT (- ra_size
)));
3092 msp430_incoming_return_addr_rtx (void)
3094 return gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
3097 /* Instruction generation stuff. */
3099 /* Generate a sequence of instructions to sign-extend an HI
3100 value into an SI value. Handles the tricky case where
3101 we are overwriting the destination. */
3104 msp430x_extendhisi (rtx
* operands
)
3106 if (REGNO (operands
[0]) == REGNO (operands
[1]))
3107 /* Low word of dest == source word. */
3108 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */
3111 /* Note: This sequence is approximately the same length as invoking a helper
3112 function to perform the sign-extension, as in:
3116 CALL __mspabi_srai_15
3119 but this version does not involve any function calls or using argument
3120 registers, so it reduces register pressure. */
3121 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */
3123 if (REGNO (operands
[0]) + 1 == REGNO (operands
[1]))
3124 /* High word of dest == source word. */
3125 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
3127 /* No overlap between dest and source. */
3128 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */
3131 /* Likewise for logical right shifts. */
3133 msp430x_logical_shift_right (rtx amount
)
3135 /* The MSP430X's logical right shift instruction - RRUM - does
3136 not use an extension word, so we cannot encode a repeat count.
3137 Try various alternatives to work around this. If the count
3138 is in a register we are stuck, hence the assert. */
3139 gcc_assert (CONST_INT_P (amount
));
3141 if (INTVAL (amount
) <= 0
3142 || INTVAL (amount
) >= 16)
3143 return "# nop logical shift.";
3145 if (INTVAL (amount
) > 0
3146 && INTVAL (amount
) < 5)
3147 return "rrum.w\t%2, %0"; /* Two bytes. */
3149 if (INTVAL (amount
) > 4
3150 && INTVAL (amount
) < 9)
3151 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
3153 /* First we logically shift right by one. Now we know
3154 that the top bit is zero and we can use the arithmetic
3155 right shift instruction to perform the rest of the shift. */
3156 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */
3159 struct gcc_target targetm
= TARGET_INITIALIZER
;
3161 #include "gt-msp430.h"