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
)
981 fprintf (asm_out_file
, "\t.long\t");
982 output_addr_const (asm_out_file
, x
);
983 fputc ('\n', asm_out_file
);
988 return default_assemble_integer (x
, size
, aligned_p
);
991 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
992 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
994 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED
, rtx x
)
1000 #undef TARGET_LEGITIMATE_CONSTANT_P
1001 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1004 msp430_legitimate_constant (machine_mode mode
, rtx x
)
1006 return ! CONST_INT_P (x
)
1008 /* GCC does not know the width of the PSImode, so make
1009 sure that it does not try to use a constant value that
1011 || (INTVAL (x
) < (1 << 20) && INTVAL (x
) >= (-1 << 20));
1015 #undef TARGET_RTX_COSTS
1016 #define TARGET_RTX_COSTS msp430_rtx_costs
1018 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED
,
1020 int outer_code ATTRIBUTE_UNUSED
,
1021 int opno ATTRIBUTE_UNUSED
,
1023 bool speed ATTRIBUTE_UNUSED
)
1028 if (GET_MODE (x
) == SImode
&& outer_code
== SET
)
1030 *total
= COSTS_N_INSNS (4);
1039 *total
= COSTS_N_INSNS (100);
1047 /* Function Entry and Exit */
1049 /* The MSP430 call frame looks like this:
1052 +--------------------+
1056 +--------------------+ <-- "arg pointer"
1058 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1060 +--------------------+
1061 | SR if this func has|
1062 | been called via an |
1064 +--------------------+ <-- SP before prologue, also AP
1066 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1068 +--------------------+ <-- "frame pointer"
1072 +--------------------+
1076 +--------------------+ <-- SP during function
1081 /* We use this to wrap all emitted insns in the prologue, so they get
1082 the "frame-related" (/f) flag set. */
1086 RTX_FRAME_RELATED_P (x
) = 1;
1090 /* This is the one spot that decides if a register is to be saved and
1091 restored in the prologue/epilogue. */
1093 msp430_preserve_reg_p (int regno
)
1095 /* PC, SP, SR, and the constant generator. */
1099 /* FIXME: add interrupt, EH, etc. */
1100 if (crtl
->calls_eh_return
)
1103 /* Shouldn't be more than the above, but just in case... */
1104 if (fixed_regs
[regno
])
1107 /* Interrupt handlers save all registers they use, even
1108 ones which are call saved. If they call other functions
1109 then *every* register is saved. */
1110 if (msp430_is_interrupt_func ())
1111 return ! crtl
->is_leaf
|| df_regs_ever_live_p (regno
);
1113 if (!call_used_regs
[regno
]
1114 && df_regs_ever_live_p (regno
))
1120 /* Compute all the frame-related fields in our machine_function
1123 msp430_compute_frame_info (void)
1127 cfun
->machine
->computed
= 1;
1128 cfun
->machine
->framesize_regs
= 0;
1129 cfun
->machine
->framesize_locals
= get_frame_size ();
1130 cfun
->machine
->framesize_outgoing
= crtl
->outgoing_args_size
;
1132 for (i
= 0; i
< ARG_POINTER_REGNUM
; i
++)
1133 if (msp430_preserve_reg_p (i
))
1135 cfun
->machine
->need_to_save
[i
] = 1;
1136 cfun
->machine
->framesize_regs
+= (TARGET_LARGE
? 4 : 2);
1139 cfun
->machine
->need_to_save
[i
] = 0;
1141 if ((cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
) & 1)
1142 cfun
->machine
->framesize_locals
++;
1144 cfun
->machine
->framesize
= (cfun
->machine
->framesize_regs
1145 + cfun
->machine
->framesize_locals
1146 + cfun
->machine
->framesize_outgoing
);
1149 /* Attribute Handling. */
1151 const char * const ATTR_INTR
= "interrupt";
1152 const char * const ATTR_WAKEUP
= "wakeup";
1153 const char * const ATTR_NAKED
= "naked";
1154 const char * const ATTR_REENT
= "reentrant";
1155 const char * const ATTR_CRIT
= "critical";
1156 const char * const ATTR_LOWER
= "lower";
1157 const char * const ATTR_UPPER
= "upper";
1158 const char * const ATTR_EITHER
= "either";
1161 has_attr (const char * attr
, tree decl
)
1163 if (decl
== NULL_TREE
)
1165 return lookup_attribute (attr
, DECL_ATTRIBUTES (decl
)) != NULL_TREE
;
1169 is_interrupt_func (tree decl
= current_function_decl
)
1171 return has_attr (ATTR_INTR
, decl
);
1174 /* Returns true if the current function has the "interrupt" attribute. */
1177 msp430_is_interrupt_func (void)
1179 return is_interrupt_func (current_function_decl
);
1183 is_wakeup_func (tree decl
= current_function_decl
)
1185 return is_interrupt_func (decl
) && has_attr (ATTR_WAKEUP
, decl
);
1189 is_naked_func (tree decl
= current_function_decl
)
1191 return has_attr (ATTR_NAKED
, decl
);
1195 is_reentrant_func (tree decl
= current_function_decl
)
1197 return has_attr (ATTR_REENT
, decl
);
1201 is_critical_func (tree decl
= current_function_decl
)
1203 return has_attr (ATTR_CRIT
, decl
);
1206 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1207 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args
1210 msp430_allocate_stack_slots_for_args (void)
1212 /* Naked functions should not allocate stack slots for arguments. */
1213 return ! is_naked_func ();
1216 /* Verify MSP430 specific attributes. */
1217 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1220 msp430_attr (tree
* node
,
1223 int flags ATTRIBUTE_UNUSED
,
1224 bool * no_add_attrs
)
1226 gcc_assert (DECL_P (* node
));
1230 gcc_assert (TREE_NAME_EQ (name
, ATTR_INTR
));
1232 tree value
= TREE_VALUE (args
);
1234 switch (TREE_CODE (value
))
1237 if ( strcmp (TREE_STRING_POINTER (value
), "reset")
1238 && strcmp (TREE_STRING_POINTER (value
), "nmi")
1239 && strcmp (TREE_STRING_POINTER (value
), "watchdog"))
1240 /* Allow the attribute to be added - the linker script
1241 being used may still recognise this name. */
1242 warning (OPT_Wattributes
,
1243 "unrecognised interrupt vector argument of %qE attribute",
1248 if (wi::gtu_p (value
, 63))
1249 /* Allow the attribute to be added - the linker script
1250 being used may still recognise this value. */
1251 warning (OPT_Wattributes
,
1252 "numeric argument of %qE attribute must be in range 0..63",
1257 warning (OPT_Wattributes
,
1258 "argument of %qE attribute is not a string constant or number",
1260 *no_add_attrs
= true;
1265 const char * message
= NULL
;
1267 if (TREE_CODE (* node
) != FUNCTION_DECL
)
1269 message
= "%qE attribute only applies to functions";
1271 else if (TREE_NAME_EQ (name
, ATTR_INTR
))
1273 if (TREE_CODE (TREE_TYPE (* node
)) == FUNCTION_TYPE
1274 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node
))))
1275 message
= "interrupt handlers must be void";
1277 else if (TREE_NAME_EQ (name
, ATTR_REENT
))
1279 if (is_naked_func (* node
))
1280 message
= "naked functions cannot be reentrant";
1281 else if (is_critical_func (* node
))
1282 message
= "critical functions cannot be reentrant";
1284 else if (TREE_NAME_EQ (name
, ATTR_CRIT
))
1286 if (is_naked_func (* node
))
1287 message
= "naked functions cannot be critical";
1288 else if (is_reentrant_func (* node
))
1289 message
= "reentranct functions cannot be critical";
1291 else if (TREE_NAME_EQ (name
, ATTR_NAKED
))
1293 if (is_critical_func (* node
))
1294 message
= "critical functions cannot be naked";
1295 else if (is_reentrant_func (* node
))
1296 message
= "reentrant functions cannot be naked";
1301 warning (OPT_Wattributes
, message
, name
);
1302 * no_add_attrs
= true;
1309 msp430_section_attr (tree
* node
,
1312 int flags ATTRIBUTE_UNUSED
,
1313 bool * no_add_attrs ATTRIBUTE_UNUSED
)
1315 gcc_assert (DECL_P (* node
));
1316 gcc_assert (args
== NULL
);
1318 const char * message
= NULL
;
1320 if (TREE_NAME_EQ (name
, ATTR_UPPER
))
1322 if (has_attr (ATTR_LOWER
, * node
))
1323 message
= "already marked with 'lower' attribute";
1324 else if (has_attr (ATTR_EITHER
, * node
))
1325 message
= "already marked with 'either' attribute";
1327 message
= "upper attribute needs a 430X cpu";
1329 else if (TREE_NAME_EQ (name
, ATTR_LOWER
))
1331 if (has_attr (ATTR_UPPER
, * node
))
1332 message
= "already marked with 'upper' attribute";
1333 else if (has_attr (ATTR_EITHER
, * node
))
1334 message
= "already marked with 'either' attribute";
1338 gcc_assert (TREE_NAME_EQ (name
, ATTR_EITHER
));
1340 if (has_attr (ATTR_LOWER
, * node
))
1341 message
= "already marked with 'lower' attribute";
1342 else if (has_attr (ATTR_UPPER
, * node
))
1343 message
= "already marked with 'upper' attribute";
1348 warning (OPT_Wattributes
, message
, name
);
1349 * no_add_attrs
= true;
1355 #undef TARGET_ATTRIBUTE_TABLE
1356 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1358 /* Table of MSP430-specific attributes. */
1359 const struct attribute_spec msp430_attribute_table
[] =
1361 /* Name min_num_args type_req, affects_type_identity
1362 max_num_args, fn_type_req
1363 decl_req handler. */
1364 { ATTR_INTR
, 0, 1, true, false, false, msp430_attr
, false },
1365 { ATTR_NAKED
, 0, 0, true, false, false, msp430_attr
, false },
1366 { ATTR_REENT
, 0, 0, true, false, false, msp430_attr
, false },
1367 { ATTR_CRIT
, 0, 0, true, false, false, msp430_attr
, false },
1368 { ATTR_WAKEUP
, 0, 0, true, false, false, msp430_attr
, false },
1370 { ATTR_LOWER
, 0, 0, true, false, false, msp430_section_attr
, false },
1371 { ATTR_UPPER
, 0, 0, true, false, false, msp430_section_attr
, false },
1372 { ATTR_EITHER
, 0, 0, true, false, false, msp430_section_attr
, false },
1374 { NULL
, 0, 0, false, false, false, NULL
, false }
1377 #undef TARGET_ASM_FUNCTION_PROLOGUE
1378 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1381 msp430_start_function (FILE *outfile
, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED
)
1385 fprintf (outfile
, "; start of function\n");
1387 if (DECL_ATTRIBUTES (current_function_decl
) != NULL_TREE
)
1389 fprintf (outfile
, "; attributes: ");
1390 if (is_naked_func ())
1391 fprintf (outfile
, "naked ");
1392 if (msp430_is_interrupt_func ())
1393 fprintf (outfile
, "interrupt ");
1394 if (is_reentrant_func ())
1395 fprintf (outfile
, "reentrant ");
1396 if (is_critical_func ())
1397 fprintf (outfile
, "critical ");
1398 if (is_wakeup_func ())
1399 fprintf (outfile
, "wakeup ");
1400 fprintf (outfile
, "\n");
1403 fprintf (outfile
, "; framesize_regs: %d\n", cfun
->machine
->framesize_regs
);
1404 fprintf (outfile
, "; framesize_locals: %d\n", cfun
->machine
->framesize_locals
);
1405 fprintf (outfile
, "; framesize_outgoing: %d\n", cfun
->machine
->framesize_outgoing
);
1406 fprintf (outfile
, "; framesize: %d\n", cfun
->machine
->framesize
);
1407 fprintf (outfile
, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM
, FRAME_POINTER_REGNUM
));
1408 fprintf (outfile
, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM
, STACK_POINTER_REGNUM
));
1411 fprintf (outfile
, "; saved regs:");
1412 for (r
= 0; r
< ARG_POINTER_REGNUM
; r
++)
1413 if (cfun
->machine
->need_to_save
[r
])
1415 fprintf (outfile
, " %s", reg_names
[r
]);
1419 fprintf (outfile
, "(none)");
1420 fprintf (outfile
, "\n");
1423 /* Common code to change the stack pointer. */
1425 increment_stack (HOST_WIDE_INT amount
)
1428 rtx sp
= stack_pointer_rtx
;
1435 inc
= GEN_INT (- amount
);
1437 F (emit_insn (gen_subpsi3 (sp
, sp
, inc
)));
1439 F (emit_insn (gen_subhi3 (sp
, sp
, inc
)));
1443 inc
= GEN_INT (amount
);
1445 emit_insn (gen_addpsi3 (sp
, sp
, inc
));
1447 emit_insn (gen_addhi3 (sp
, sp
, inc
));
1452 msp430_start_function (FILE *file
, const char *name
, tree decl
)
1456 int_attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
1457 if (int_attr
!= NULL_TREE
)
1459 tree intr_vector
= TREE_VALUE (int_attr
);
1461 if (intr_vector
!= NULL_TREE
)
1465 intr_vector
= TREE_VALUE (intr_vector
);
1467 /* The interrupt attribute has a vector value. Turn this into a
1468 section name, switch to that section and put the address of
1469 the current function into that vector slot. Note msp430_attr()
1470 has already verified the vector name for us. */
1471 if (TREE_CODE (intr_vector
) == STRING_CST
)
1472 sprintf (buf
, "__interrupt_vector_%.80s",
1473 TREE_STRING_POINTER (intr_vector
));
1474 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1475 sprintf (buf
, "__interrupt_vector_%u",
1476 (unsigned int) TREE_INT_CST_LOW (intr_vector
));
1478 switch_to_section (get_section (buf
, SECTION_CODE
, decl
));
1479 fputs ("\t.word\t", file
);
1480 assemble_name (file
, name
);
1486 switch_to_section (function_section (decl
));
1487 ASM_OUTPUT_FUNCTION_LABEL (file
, name
, decl
);
1490 static const char * const lower_prefix
= ".lower";
1491 static const char * const upper_prefix
= ".upper";
1492 static const char * const either_prefix
= ".either";
1494 /* Generate a prefix for a section name, based upon
1495 the region into which the object should be placed. */
1498 gen_prefix (tree decl
)
1500 if (DECL_ONE_ONLY (decl
))
1503 /* If the user has specified a particular section then do not use any prefix. */
1504 if (has_attr ("section", decl
))
1507 /* If the object has __attribute__((lower)) then use the ".lower." prefix. */
1508 if (has_attr (ATTR_LOWER
, decl
))
1509 return lower_prefix
;
1511 /* If we are compiling for the MSP430 then we do not support the upper region. */
1515 if (has_attr (ATTR_UPPER
, decl
))
1516 return upper_prefix
;
1518 if (has_attr (ATTR_EITHER
, decl
))
1519 return either_prefix
;
1521 if (TREE_CODE (decl
) == FUNCTION_DECL
)
1523 if (msp430_code_region
== LOWER
)
1524 return lower_prefix
;
1526 if (msp430_code_region
== UPPER
)
1527 return upper_prefix
;
1529 if (msp430_code_region
== EITHER
)
1530 return either_prefix
;
1534 if (msp430_data_region
== LOWER
)
1535 return lower_prefix
;
1537 if (msp430_data_region
== UPPER
)
1538 return upper_prefix
;
1540 if (msp430_data_region
== EITHER
)
1541 return either_prefix
;
1547 #undef TARGET_ASM_SELECT_SECTION
1548 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1551 msp430_select_section (tree decl
, int reloc
, unsigned HOST_WIDE_INT align
)
1553 gcc_assert (decl
!= NULL_TREE
);
1555 if (TREE_CODE (decl
) == STRING_CST
1556 || TREE_CODE (decl
) == CONSTRUCTOR
1557 || TREE_CODE (decl
) == INTEGER_CST
1558 || TREE_CODE (decl
) == VECTOR_CST
1559 || TREE_CODE (decl
) == COMPLEX_CST
)
1560 return default_select_section (decl
, reloc
, align
);
1562 /* In large mode we must make sure that interrupt handlers are put into
1563 low memory as the vector table only accepts 16-bit addresses. */
1564 if (TARGET_LARGE
&& TREE_CODE (decl
) == FUNCTION_DECL
&& is_interrupt_func (decl
))
1565 return get_section (".lowtext", SECTION_CODE
| SECTION_WRITE
, decl
);
1567 const char * prefix
= gen_prefix (decl
);
1570 if (TREE_CODE (decl
) == FUNCTION_DECL
)
1571 return text_section
;
1573 return default_select_section (decl
, reloc
, align
);
1577 switch (categorize_decl_for_section (decl
, reloc
))
1579 case SECCAT_TEXT
: sec
= ".text"; break;
1580 case SECCAT_DATA
: sec
= ".data"; break;
1581 case SECCAT_BSS
: sec
= ".bss"; break;
1582 case SECCAT_RODATA
: sec
= ".rodata"; break;
1584 case SECCAT_RODATA_MERGE_STR
:
1585 case SECCAT_RODATA_MERGE_STR_INIT
:
1586 case SECCAT_RODATA_MERGE_CONST
:
1587 case SECCAT_SRODATA
:
1588 case SECCAT_DATA_REL
:
1589 case SECCAT_DATA_REL_LOCAL
:
1590 case SECCAT_DATA_REL_RO
:
1591 case SECCAT_DATA_REL_RO_LOCAL
:
1596 return default_select_section (decl
, reloc
, align
);
1602 const char * dec_name
= DECL_SECTION_NAME (decl
);
1603 char * name
= ACONCAT ((prefix
, sec
, dec_name
, NULL
));
1605 return get_named_section (decl
, name
, 0);
1608 #undef TARGET_ASM_FUNCTION_SECTION
1609 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1612 msp430_function_section (tree decl
, enum node_frequency freq
, bool startup
, bool exit
)
1616 gcc_assert (DECL_SECTION_NAME (decl
) != NULL
);
1617 name
= DECL_SECTION_NAME (decl
);
1619 const char * prefix
= gen_prefix (decl
);
1621 || strncmp (name
, prefix
, strlen (prefix
)) == 0)
1622 return default_function_section (decl
, freq
, startup
, exit
);
1624 name
= ACONCAT ((prefix
, name
, NULL
));
1625 return get_named_section (decl
, name
, 0);
1628 #undef TARGET_SECTION_TYPE_FLAGS
1629 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1632 msp430_section_type_flags (tree decl
, const char * name
, int reloc
)
1634 if (strncmp (name
, lower_prefix
, strlen (lower_prefix
)) == 0)
1635 name
+= strlen (lower_prefix
);
1636 else if (strncmp (name
, upper_prefix
, strlen (upper_prefix
)) == 0)
1637 name
+= strlen (upper_prefix
);
1638 else if (strncmp (name
, either_prefix
, strlen (either_prefix
)) == 0)
1639 name
+= strlen (either_prefix
);
1641 return default_section_type_flags (decl
, name
, reloc
);
1644 #undef TARGET_ASM_UNIQUE_SECTION
1645 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1648 msp430_unique_section (tree decl
, int reloc
)
1650 gcc_assert (decl
!= NULL_TREE
);
1652 /* In large mode we must make sure that interrupt handlers are put into
1653 low memory as the vector table only accepts 16-bit addresses. */
1654 if (TARGET_LARGE
&& TREE_CODE (decl
) == FUNCTION_DECL
&& is_interrupt_func (decl
))
1656 set_decl_section_name (decl
, ".lowtext");
1660 default_unique_section (decl
, reloc
);
1662 const char * prefix
;
1664 if ( TREE_CODE (decl
) == STRING_CST
1665 || TREE_CODE (decl
) == CONSTRUCTOR
1666 || TREE_CODE (decl
) == INTEGER_CST
1667 || TREE_CODE (decl
) == VECTOR_CST
1668 || TREE_CODE (decl
) == COMPLEX_CST
1669 || (prefix
= gen_prefix (decl
)) == NULL
1673 const char * dec_name
= DECL_SECTION_NAME (decl
);
1674 char * name
= ACONCAT ((prefix
, dec_name
, NULL
));
1676 set_decl_section_name (decl
, name
);
1679 /* Emit a declaration of a common symbol.
1680 If a data region is in use then put the symbol into the
1681 equivalent .bss section instead. */
1684 msp430_output_aligned_decl_common (FILE * stream
,
1687 unsigned HOST_WIDE_INT size
,
1690 if (msp430_data_region
== ANY
)
1692 fprintf (stream
, COMMON_ASM_OP
);
1693 assemble_name (stream
, name
);
1694 fprintf (stream
, "," HOST_WIDE_INT_PRINT_UNSIGNED
",%u\n",
1695 size
, align
/ BITS_PER_UNIT
);
1702 sec
= msp430_select_section (decl
, 0, align
);
1704 switch (msp430_data_region
)
1706 case UPPER
: sec
= get_named_section (NULL
, ".upper.bss", 0); break;
1707 case LOWER
: sec
= get_named_section (NULL
, ".lower.bss", 0); break;
1708 case EITHER
: sec
= get_named_section (NULL
, ".either.bss", 0); break;
1712 gcc_assert (sec
!= NULL
);
1714 switch_to_section (sec
);
1715 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
1716 targetm
.asm_out
.globalize_label (stream
, name
);
1717 ASM_WEAKEN_LABEL (stream
, name
);
1718 ASM_OUTPUT_LABEL (stream
, name
);
1719 ASM_OUTPUT_SKIP (stream
, size
? size
: 1);
1724 msp430_do_not_relax_short_jumps (void)
1726 /* When placing code into "either" low or high memory we do not want the linker
1727 to grow the size of sections, which it can do if it is encounters a branch to
1728 a label that is too far away. So we tell the cbranch patterns to avoid using
1729 short jumps when there is a chance that the instructions will end up in a low
1732 msp430_code_region
== EITHER
1733 || msp430_code_region
== LOWER
1734 || has_attr (ATTR_EITHER
, current_function_decl
)
1735 || has_attr (ATTR_LOWER
, current_function_decl
);
1740 MSP430_BUILTIN_BIC_SR
,
1741 MSP430_BUILTIN_BIS_SR
,
1742 MSP430_BUILTIN_DELAY_CYCLES
,
1746 static GTY(()) tree msp430_builtins
[(int) MSP430_BUILTIN_max
];
1749 msp430_init_builtins (void)
1751 tree void_ftype_int
= build_function_type_list (void_type_node
, integer_type_node
, NULL
);
1752 tree void_ftype_longlong
= build_function_type_list (void_type_node
, long_long_integer_type_node
, NULL
);
1754 msp430_builtins
[MSP430_BUILTIN_BIC_SR
] =
1755 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int
,
1756 MSP430_BUILTIN_BIC_SR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1758 msp430_builtins
[MSP430_BUILTIN_BIS_SR
] =
1759 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int
,
1760 MSP430_BUILTIN_BIS_SR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1762 msp430_builtins
[MSP430_BUILTIN_DELAY_CYCLES
] =
1763 add_builtin_function ( "__delay_cycles", void_ftype_longlong
,
1764 MSP430_BUILTIN_DELAY_CYCLES
, BUILT_IN_MD
, NULL
, NULL_TREE
);
1768 msp430_builtin_decl (unsigned code
, bool initialize ATTRIBUTE_UNUSED
)
1772 case MSP430_BUILTIN_BIC_SR
:
1773 case MSP430_BUILTIN_BIS_SR
:
1774 case MSP430_BUILTIN_DELAY_CYCLES
:
1775 return msp430_builtins
[code
];
1777 return error_mark_node
;
1781 /* These constants are really register reads, which are faster than
1782 regular constants. */
1784 cg_magic_constant (HOST_WIDE_INT c
)
1802 msp430_expand_delay_cycles (rtx arg
)
1804 HOST_WIDE_INT i
, c
, n
;
1805 /* extra cycles for MSP430X instructions */
1806 #define CYCX(M,X) (msp430x ? (X) : (M))
1808 if (GET_CODE (arg
) != CONST_INT
)
1810 error ("__delay_cycles() only takes constant arguments");
1816 if (HOST_BITS_PER_WIDE_INT
> 32)
1820 error ("__delay_cycles only takes non-negative cycle counts.");
1825 emit_insn (gen_delay_cycles_start (arg
));
1827 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
1828 if (c
> 3 * 0xffff + CYCX (7, 10))
1831 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long (x<=0xffff) loop */
1832 if (c
>= 0x10000 * 7 + CYCX (14, 16))
1835 c
-= CYCX (14, 16) + 7 * 0x10000;
1838 if ((unsigned long long) i
> 0xffffffffULL
)
1840 error ("__delay_cycles is limited to 32-bit loop counts.");
1846 i
= (c
- CYCX (14, 16)) / 7;
1847 c
-= CYCX (14, 16) + i
* 7;
1850 if (cg_magic_constant (i
& 0xffff))
1852 if (cg_magic_constant ((i
>> 16) & 0xffff))
1856 emit_insn (gen_delay_cycles_32x (GEN_INT (i
), GEN_INT (n
- c
)));
1858 emit_insn (gen_delay_cycles_32 (GEN_INT (i
), GEN_INT (n
- c
)));
1861 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */
1865 i
= (c
- CYCX (7, 10)) / 3;
1866 c
-= CYCX (7, 10) + i
* 3;
1868 if (cg_magic_constant (i
))
1872 emit_insn (gen_delay_cycles_16x (GEN_INT (i
), GEN_INT (n
- c
)));
1874 emit_insn (gen_delay_cycles_16 (GEN_INT (i
), GEN_INT (n
- c
)));
1879 emit_insn (gen_delay_cycles_2 ());
1885 emit_insn (gen_delay_cycles_1 ());
1889 emit_insn (gen_delay_cycles_end (arg
));
1895 msp430_expand_builtin (tree exp
,
1896 rtx target ATTRIBUTE_UNUSED
,
1897 rtx subtarget ATTRIBUTE_UNUSED
,
1898 machine_mode mode ATTRIBUTE_UNUSED
,
1899 int ignore ATTRIBUTE_UNUSED
)
1901 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
1902 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
1903 rtx arg1
= expand_normal (CALL_EXPR_ARG (exp
, 0));
1905 if (fcode
== MSP430_BUILTIN_DELAY_CYCLES
)
1906 return msp430_expand_delay_cycles (arg1
);
1908 if (! msp430_is_interrupt_func ())
1910 error ("MSP430 builtin functions only work inside interrupt handlers");
1914 if (! REG_P (arg1
) && ! CONSTANT_P (arg1
))
1915 arg1
= force_reg (mode
, arg1
);
1919 case MSP430_BUILTIN_BIC_SR
: emit_insn (gen_bic_SR (arg1
)); break;
1920 case MSP430_BUILTIN_BIS_SR
: emit_insn (gen_bis_SR (arg1
)); break;
1922 internal_error ("bad builtin code");
1928 #undef TARGET_INIT_BUILTINS
1929 #define TARGET_INIT_BUILTINS msp430_init_builtins
1931 #undef TARGET_EXPAND_BUILTIN
1932 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
1934 #undef TARGET_BUILTIN_DECL
1935 #define TARGET_BUILTIN_DECL msp430_builtin_decl
1938 msp430_expand_prologue (void)
1942 /* Always use stack_pointer_rtx instead of calling
1943 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
1944 that there is a single rtx representing the stack pointer,
1945 namely stack_pointer_rtx, and uses == to recognize it. */
1946 rtx sp
= stack_pointer_rtx
;
1949 if (is_naked_func ())
1951 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
1952 examines the output of the gen_prologue() function. */
1953 emit_insn (gen_rtx_CLOBBER (VOIDmode
, GEN_INT (0)));
1957 emit_insn (gen_prologue_start_marker ());
1959 if (is_critical_func ())
1961 emit_insn (gen_push_intr_state ());
1962 emit_insn (gen_disable_interrupts ());
1964 else if (is_reentrant_func ())
1965 emit_insn (gen_disable_interrupts ());
1967 if (!cfun
->machine
->computed
)
1968 msp430_compute_frame_info ();
1970 if (flag_stack_usage_info
)
1971 current_function_static_stack_size
= cfun
->machine
->framesize
;
1973 if (crtl
->args
.pretend_args_size
)
1977 gcc_assert (crtl
->args
.pretend_args_size
== 2);
1979 p
= emit_insn (gen_grow_and_swap ());
1981 /* Document the stack decrement... */
1982 note
= F (gen_rtx_SET (stack_pointer_rtx
,
1983 gen_rtx_MINUS (Pmode
, stack_pointer_rtx
, GEN_INT (2))));
1984 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
1986 /* ...and the establishment of a new location for the return address. */
1987 note
= F (gen_rtx_SET (gen_rtx_MEM (Pmode
,
1988 gen_rtx_PLUS (Pmode
,
1992 add_reg_note (p
, REG_CFA_OFFSET
, note
);
1996 for (i
= 15; i
>= 4; i
--)
1997 if (cfun
->machine
->need_to_save
[i
])
2002 for (seq
= i
- 1; seq
>= 4 && cfun
->machine
->need_to_save
[seq
]; seq
--)
2008 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */
2009 p
= F (emit_insn (gen_pushm (gen_rtx_REG (Pmode
, i
),
2012 note
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (count
+ 1));
2014 XVECEXP (note
, 0, 0)
2015 = F (gen_rtx_SET (stack_pointer_rtx
,
2016 gen_rtx_PLUS (Pmode
,
2018 GEN_INT (count
* (TARGET_LARGE
? -4 : -2)))));
2020 /* *sp-- = R[i-j] */
2024 for (j
= 0; j
< count
; j
++)
2027 int ofs
= (count
- j
- 1) * (TARGET_LARGE
? 4 : 2);
2030 addr
= gen_rtx_PLUS (Pmode
, sp
, GEN_INT (ofs
));
2032 addr
= stack_pointer_rtx
;
2034 XVECEXP (note
, 0, j
+ 1) =
2035 F (gen_rtx_SET (gen_rtx_MEM (Pmode
, addr
),
2036 gen_rtx_REG (Pmode
, i
- j
)) );
2039 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
2043 F (emit_insn (gen_push (gen_rtx_REG (Pmode
, i
))));
2046 if (frame_pointer_needed
)
2047 F (emit_move_insn (gen_rtx_REG (Pmode
, FRAME_POINTER_REGNUM
), sp
));
2049 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
2051 increment_stack (- fs
);
2053 emit_insn (gen_prologue_end_marker ());
2057 msp430_expand_epilogue (int is_eh
)
2063 if (is_naked_func ())
2065 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2066 examines the output of the gen_epilogue() function. */
2067 emit_insn (gen_rtx_CLOBBER (VOIDmode
, GEN_INT (0)));
2071 if (cfun
->machine
->need_to_save
[10])
2073 /* Check for a helper function. */
2074 helper_n
= 7; /* For when the loop below never sees a match. */
2075 for (i
= 9; i
>= 4; i
--)
2076 if (!cfun
->machine
->need_to_save
[i
])
2080 if (cfun
->machine
->need_to_save
[i
])
2089 emit_insn (gen_epilogue_start_marker ());
2091 if (cfun
->decl
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun
->decl
)), "main") == 0)
2092 emit_insn (gen_msp430_refsym_need_exit ());
2094 if (is_wakeup_func ())
2095 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2096 status register current residing on the stack. When this function
2097 executes its RETI instruction the SR will be updated with this saved
2098 value, thus ensuring that the processor is woken up from any low power
2099 state in which it may be residing. */
2100 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2102 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
2104 increment_stack (fs
);
2108 /* We need to add the right "SP" register save just after the
2109 regular ones, so that when we pop it off we're in the EH
2110 return frame, not this one. This overwrites our own return
2111 address, but we're not going to be returning anyway. */
2112 rtx r12
= gen_rtx_REG (Pmode
, 12);
2113 rtx (*addPmode
)(rtx
, rtx
, rtx
) = TARGET_LARGE
? gen_addpsi3
: gen_addhi3
;
2115 /* R12 will hold the new SP. */
2116 i
= cfun
->machine
->framesize_regs
;
2117 emit_move_insn (r12
, stack_pointer_rtx
);
2118 emit_insn (addPmode (r12
, r12
, EH_RETURN_STACKADJ_RTX
));
2119 emit_insn (addPmode (r12
, r12
, GEN_INT (i
)));
2120 emit_move_insn (gen_rtx_MEM (Pmode
, plus_constant (Pmode
, stack_pointer_rtx
, i
)), r12
);
2123 for (i
= 4; i
<= 15; i
++)
2124 if (cfun
->machine
->need_to_save
[i
])
2128 for (seq
= i
+ 1; seq
<= 15 && cfun
->machine
->need_to_save
[seq
]; seq
++)
2134 /* Note: With TARGET_LARGE we still use
2135 POPM as POPX.A is two bytes bigger. */
2136 emit_insn (gen_popm (stack_pointer_rtx
, GEN_INT (seq
- 1),
2140 else if (i
== 11 - helper_n
2141 && ! msp430_is_interrupt_func ()
2142 && ! is_reentrant_func ()
2143 && ! is_critical_func ()
2144 && crtl
->args
.pretend_args_size
== 0
2145 /* Calling the helper takes as many bytes as the POP;RET sequence. */
2149 emit_insn (gen_epilogue_helper (GEN_INT (helper_n
)));
2153 emit_insn (gen_pop (gen_rtx_REG (Pmode
, i
)));
2158 /* Also pop SP, which puts us into the EH return frame. Except
2159 that you can't "pop" sp, you have to just load it off the
2161 emit_move_insn (stack_pointer_rtx
, gen_rtx_MEM (Pmode
, stack_pointer_rtx
));
2164 if (crtl
->args
.pretend_args_size
)
2165 emit_insn (gen_swap_and_shrink ());
2167 if (is_critical_func ())
2168 emit_insn (gen_pop_intr_state ());
2169 else if (is_reentrant_func ())
2170 emit_insn (gen_enable_interrupts ());
2172 emit_jump_insn (gen_msp_return ());
2175 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2176 m32c_emit_eh_epilogue. */
2178 msp430_eh_return_stackadj_rtx (void)
2180 if (!cfun
->machine
->eh_stack_adjust
)
2184 sa
= gen_rtx_REG (Pmode
, 15);
2185 cfun
->machine
->eh_stack_adjust
= sa
;
2187 return cfun
->machine
->eh_stack_adjust
;
2190 /* This function is called before reload, to "fix" the stack in
2191 preparation for an EH return. */
2193 msp430_expand_eh_return (rtx eh_handler
)
2195 /* These are all Pmode */
2196 rtx ap
, sa
, ra
, tmp
;
2198 ap
= arg_pointer_rtx
;
2199 sa
= msp430_eh_return_stackadj_rtx ();
2203 tmp
= gen_rtx_PLUS (Pmode
, ap
, sa
);
2204 tmp
= plus_constant (Pmode
, tmp
, TARGET_LARGE
? -4 : -2);
2205 tmp
= gen_rtx_MEM (Pmode
, tmp
);
2206 emit_move_insn (tmp
, ra
);
2209 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
2210 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2212 msp430_init_dwarf_reg_sizes_extra (tree address
)
2215 rtx addr
= expand_normal (address
);
2216 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
2221 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
2223 unsigned int dnum
= DWARF_FRAME_REGNUM (i
);
2224 unsigned int rnum
= DWARF2_FRAME_REG_OUT (dnum
, 1);
2226 if (rnum
< DWARF_FRAME_REGISTERS
)
2228 HOST_WIDE_INT offset
= rnum
* GET_MODE_SIZE (QImode
);
2230 emit_move_insn (adjust_address (mem
, QImode
, offset
),
2231 gen_int_mode (4, QImode
));
2236 /* This is a list of MD patterns that implement fixed-count shifts. */
2242 rtx (*genfunc
)(rtx
,rtx
);
2244 const_shift_helpers
[] =
2246 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2248 CSH ("slli", 1, 1, slli_1
),
2249 CSH ("slll", 1, 1, slll_1
),
2250 CSH ("slll", 2, 1, slll_2
),
2252 CSH ("srai", 1, 0, srai_1
),
2253 CSH ("sral", 1, 0, sral_1
),
2254 CSH ("sral", 2, 0, sral_2
),
2256 CSH ("srll", 1, 0, srll_1
),
2257 CSH ("srll", 2, 1, srll_2x
),
2262 /* The MSP430 ABI defines a number of helper functions that should be
2263 used for, for example, 32-bit shifts. This function is called to
2264 emit such a function, using the table above to optimize some
2267 msp430_expand_helper (rtx
*operands
, const char *helper_name
, bool const_variants
)
2270 char *helper_const
= NULL
;
2273 machine_mode arg0mode
= GET_MODE (operands
[0]);
2274 machine_mode arg1mode
= GET_MODE (operands
[1]);
2275 machine_mode arg2mode
= GET_MODE (operands
[2]);
2276 int have_430x
= msp430x
? 1 : 0;
2278 if (CONST_INT_P (operands
[2]))
2282 for (i
=0; const_shift_helpers
[i
].name
; i
++)
2284 if (const_shift_helpers
[i
].need_430x
<= have_430x
2285 && strcmp (helper_name
, const_shift_helpers
[i
].name
) == 0
2286 && INTVAL (operands
[2]) == const_shift_helpers
[i
].count
)
2288 emit_insn (const_shift_helpers
[i
].genfunc (operands
[0], operands
[1]));
2294 if (arg1mode
== VOIDmode
)
2295 arg1mode
= arg0mode
;
2296 if (arg2mode
== VOIDmode
)
2297 arg2mode
= arg0mode
;
2299 if (arg1mode
== SImode
)
2306 && CONST_INT_P (operands
[2])
2307 && INTVAL (operands
[2]) >= 1
2308 && INTVAL (operands
[2]) <= 15)
2310 /* Note that the INTVAL is limited in value and length by the conditional above. */
2311 int len
= strlen (helper_name
) + 4;
2312 helper_const
= (char *) xmalloc (len
);
2313 snprintf (helper_const
, len
, "%s_%d", helper_name
, (int) INTVAL (operands
[2]));
2316 emit_move_insn (gen_rtx_REG (arg1mode
, 12),
2319 emit_move_insn (gen_rtx_REG (arg2mode
, arg2
),
2322 c
= gen_call_value_internal (gen_rtx_REG (arg0mode
, 12),
2323 gen_rtx_SYMBOL_REF (VOIDmode
, helper_const
? helper_const
: helper_name
),
2325 c
= emit_call_insn (c
);
2326 RTL_CONST_CALL_P (c
) = 1;
2329 use_regs (&f
, 12, arg1sz
);
2331 use_regs (&f
, arg2
, 1);
2332 add_function_usage_to (c
, f
);
2334 emit_move_insn (operands
[0],
2335 gen_rtx_REG (arg0mode
, 12));
2338 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
2340 msp430_fixup_compare_operands (machine_mode my_mode
, rtx
* operands
)
2342 /* constants we're looking for, not constants which are allowed. */
2343 int const_op_idx
= 1;
2345 if (msp430_reversible_cmp_operator (operands
[0], VOIDmode
))
2348 if (GET_CODE (operands
[const_op_idx
]) != REG
2349 && GET_CODE (operands
[const_op_idx
]) != MEM
)
2350 operands
[const_op_idx
] = copy_to_mode_reg (my_mode
, operands
[const_op_idx
]);
2353 /* Simplify_gen_subreg() doesn't handle memory references the way we
2354 need it to below, so we use this function for when we must get a
2355 valid subreg in a "natural" state. */
2357 msp430_subreg (machine_mode mode
, rtx r
, machine_mode omode
, int byte
)
2361 if (GET_CODE (r
) == SUBREG
2362 && SUBREG_BYTE (r
) == 0)
2364 rtx ireg
= SUBREG_REG (r
);
2365 machine_mode imode
= GET_MODE (ireg
);
2367 /* special case for (HI (SI (PSI ...), 0)) */
2368 if (imode
== PSImode
2371 rv
= gen_rtx_SUBREG (mode
, ireg
, byte
);
2373 rv
= simplify_gen_subreg (mode
, ireg
, imode
, byte
);
2375 else if (GET_CODE (r
) == MEM
)
2376 rv
= adjust_address (r
, mode
, byte
);
2377 else if (GET_CODE (r
) == SYMBOL_REF
2378 && (byte
== 0 || byte
== 2)
2381 rv
= gen_rtx_ZERO_EXTRACT (HImode
, r
, GEN_INT (16), GEN_INT (8*byte
));
2382 rv
= gen_rtx_CONST (HImode
, r
);
2385 rv
= simplify_gen_subreg (mode
, r
, omode
, byte
);
2393 /* Called by movsi_x to generate the HImode operands. */
2395 msp430_split_movsi (rtx
*operands
)
2397 rtx op00
, op02
, op10
, op12
;
2399 op00
= msp430_subreg (HImode
, operands
[0], SImode
, 0);
2400 op02
= msp430_subreg (HImode
, operands
[0], SImode
, 2);
2402 if (GET_CODE (operands
[1]) == CONST
2403 || GET_CODE (operands
[1]) == SYMBOL_REF
)
2405 op10
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (0));
2406 op10
= gen_rtx_CONST (HImode
, op10
);
2407 op12
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16), GEN_INT (16));
2408 op12
= gen_rtx_CONST (HImode
, op12
);
2412 op10
= msp430_subreg (HImode
, operands
[1], SImode
, 0);
2413 op12
= msp430_subreg (HImode
, operands
[1], SImode
, 2);
2416 if (rtx_equal_p (operands
[0], operands
[1]))
2423 else if (rtx_equal_p (op00
, op12
)
2424 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
2425 || (REG_P (op00
) && reg_mentioned_p (op00
, op10
))
2426 /* Or storing (rN) into mem (rN). */
2427 || (REG_P (op10
) && reg_mentioned_p (op10
, op00
))
2445 /* The MSPABI specifies the names of various helper functions, many of
2446 which are compatible with GCC's helpers. This table maps the GCC
2447 name to the MSPABI name. */
2450 char const * const gcc_name
;
2451 char const * const ti_name
;
2453 helper_function_name_mappings
[] =
2455 /* Floating point to/from integer conversions. */
2456 { "__truncdfsf2", "__mspabi_cvtdf" },
2457 { "__extendsfdf2", "__mspabi_cvtfd" },
2458 { "__fixdfhi", "__mspabi_fixdi" },
2459 { "__fixdfsi", "__mspabi_fixdli" },
2460 { "__fixdfdi", "__mspabi_fixdlli" },
2461 { "__fixunsdfhi", "__mspabi_fixdu" },
2462 { "__fixunsdfsi", "__mspabi_fixdul" },
2463 { "__fixunsdfdi", "__mspabi_fixdull" },
2464 { "__fixsfhi", "__mspabi_fixfi" },
2465 { "__fixsfsi", "__mspabi_fixfli" },
2466 { "__fixsfdi", "__mspabi_fixflli" },
2467 { "__fixunsfhi", "__mspabi_fixfu" },
2468 { "__fixunsfsi", "__mspabi_fixful" },
2469 { "__fixunsfdi", "__mspabi_fixfull" },
2470 { "__floathisf", "__mspabi_fltif" },
2471 { "__floatsisf", "__mspabi_fltlif" },
2472 { "__floatdisf", "__mspabi_fltllif" },
2473 { "__floathidf", "__mspabi_fltid" },
2474 { "__floatsidf", "__mspabi_fltlid" },
2475 { "__floatdidf", "__mspabi_fltllid" },
2476 { "__floatunhisf", "__mspabi_fltuf" },
2477 { "__floatunsisf", "__mspabi_fltulf" },
2478 { "__floatundisf", "__mspabi_fltullf" },
2479 { "__floatunhidf", "__mspabi_fltud" },
2480 { "__floatunsidf", "__mspabi_fltuld" },
2481 { "__floatundidf", "__mspabi_fltulld" },
2483 /* Floating point comparisons. */
2484 /* GCC uses individual functions for each comparison, TI uses one
2485 compare <=> function. */
2487 /* Floating point arithmatic */
2488 { "__adddf3", "__mspabi_addd" },
2489 { "__addsf3", "__mspabi_addf" },
2490 { "__divdf3", "__mspabi_divd" },
2491 { "__divsf3", "__mspabi_divf" },
2492 { "__muldf3", "__mspabi_mpyd" },
2493 { "__mulsf3", "__mspabi_mpyf" },
2494 { "__subdf3", "__mspabi_subd" },
2495 { "__subsf3", "__mspabi_subf" },
2496 /* GCC does not use helper functions for negation */
2498 /* Integer multiply, divide, remainder. */
2499 { "__mulhi3", "__mspabi_mpyi" },
2500 { "__mulsi3", "__mspabi_mpyl" },
2501 { "__muldi3", "__mspabi_mpyll" },
2503 /* Clarify signed vs unsigned first. */
2504 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */
2505 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */
2508 { "__divhi3", "__mspabi_divi" },
2509 { "__divsi3", "__mspabi_divli" },
2510 { "__divdi3", "__mspabi_divlli" },
2511 { "__udivhi3", "__mspabi_divu" },
2512 { "__udivsi3", "__mspabi_divlu" },
2513 { "__udivdi3", "__mspabi_divllu" },
2514 { "__modhi3", "__mspabi_remi" },
2515 { "__modsi3", "__mspabi_remli" },
2516 { "__moddi3", "__mspabi_remlli" },
2517 { "__umodhi3", "__mspabi_remu" },
2518 { "__umodsi3", "__mspabi_remul" },
2519 { "__umoddi3", "__mspabi_remull" },
2521 /* Bitwise operations. */
2522 /* Rotation - no rotation support yet. */
2523 /* Logical left shift - gcc already does these itself. */
2524 /* Arithmetic left shift - gcc already does these itself. */
2525 /* Arithmetic right shift - gcc already does these itself. */
2530 /* Returns true if the current MCU supports an F5xxx series
2531 hardware multiper. */
2534 msp430_use_f5_series_hwmult (void)
2536 static const char * cached_match
= NULL
;
2537 static bool cached_result
;
2539 if (msp430_hwmult_type
== F5SERIES
)
2542 if (target_mcu
== NULL
|| msp430_hwmult_type
!= AUTO
)
2545 if (target_mcu
== cached_match
)
2546 return cached_result
;
2548 cached_match
= target_mcu
;
2550 if (strncasecmp (target_mcu
, "msp430f5", 8) == 0)
2551 return cached_result
= true;
2552 if (strncasecmp (target_mcu
, "msp430fr5", 9) == 0)
2553 return cached_result
= true;
2554 if (strncasecmp (target_mcu
, "msp430f6", 8) == 0)
2555 return cached_result
= true;
2557 static const char * known_f5_mult_mcus
[] =
2559 "cc430f5123", "cc430f5125", "cc430f5133",
2560 "cc430f5135", "cc430f5137", "cc430f5143",
2561 "cc430f5145", "cc430f5147", "cc430f6125",
2562 "cc430f6126", "cc430f6127", "cc430f6135",
2563 "cc430f6137", "cc430f6143", "cc430f6145",
2564 "cc430f6147", "msp430bt5190", "msp430sl5438a",
2569 for (i
= ARRAY_SIZE (known_f5_mult_mcus
); i
--;)
2570 if (strcasecmp (target_mcu
, known_f5_mult_mcus
[i
]) == 0)
2571 return cached_result
= true;
2573 return cached_result
= false;
2576 /* Returns true if the current MCU has a second generation
2577 32-bit hardware multiplier. */
2580 use_32bit_hwmult (void)
2582 static const char * known_32bit_mult_mcus
[] =
2584 "msp430f4783", "msp430f4793", "msp430f4784",
2585 "msp430f4794", "msp430f47126", "msp430f47127",
2586 "msp430f47163", "msp430f47173", "msp430f47183",
2587 "msp430f47193", "msp430f47166", "msp430f47176",
2588 "msp430f47186", "msp430f47196", "msp430f47167",
2589 "msp430f47177", "msp430f47187", "msp430f47197"
2591 static const char * cached_match
= NULL
;
2592 static bool cached_result
;
2595 if (msp430_hwmult_type
== LARGE
)
2598 if (target_mcu
== NULL
|| msp430_hwmult_type
!= AUTO
)
2601 if (target_mcu
== cached_match
)
2602 return cached_result
;
2604 cached_match
= target_mcu
;
2605 for (i
= ARRAY_SIZE (known_32bit_mult_mcus
); i
--;)
2606 if (strcasecmp (target_mcu
, known_32bit_mult_mcus
[i
]) == 0)
2607 return cached_result
= true;
2609 return cached_result
= false;
2612 /* Returns true if the current MCU does not have a
2613 hardware multiplier of any kind. */
2616 msp430_no_hwmult (void)
2618 static const char * known_nomult_mcus
[] =
2620 "msp430c091", "msp430c092", "msp430c111",
2621 "msp430c1111", "msp430c112", "msp430c1121",
2622 "msp430c1331", "msp430c1351", "msp430c311s",
2623 "msp430c312", "msp430c313", "msp430c314",
2624 "msp430c315", "msp430c323", "msp430c325",
2625 "msp430c412", "msp430c413", "msp430e112",
2626 "msp430e313", "msp430e315", "msp430e325",
2627 "msp430f110", "msp430f1101", "msp430f1101a",
2628 "msp430f1111", "msp430f1111a", "msp430f112",
2629 "msp430f1121", "msp430f1121a", "msp430f1122",
2630 "msp430f1132", "msp430f122", "msp430f1222",
2631 "msp430f123", "msp430f1232", "msp430f133",
2632 "msp430f135", "msp430f155", "msp430f156",
2633 "msp430f157", "msp430f2001", "msp430f2002",
2634 "msp430f2003", "msp430f2011", "msp430f2012",
2635 "msp430f2013", "msp430f2101", "msp430f2111",
2636 "msp430f2112", "msp430f2121", "msp430f2122",
2637 "msp430f2131", "msp430f2132", "msp430f2232",
2638 "msp430f2234", "msp430f2252", "msp430f2254",
2639 "msp430f2272", "msp430f2274", "msp430f412",
2640 "msp430f413", "msp430f4132", "msp430f415",
2641 "msp430f4152", "msp430f417", "msp430f4250",
2642 "msp430f4260", "msp430f4270", "msp430f435",
2643 "msp430f4351", "msp430f436", "msp430f4361",
2644 "msp430f437", "msp430f4371", "msp430f438",
2645 "msp430f439", "msp430f477", "msp430f478",
2646 "msp430f479", "msp430fe423", "msp430fe4232",
2647 "msp430fe423a", "msp430fe4242", "msp430fe425",
2648 "msp430fe4252", "msp430fe425a", "msp430fe427",
2649 "msp430fe4272", "msp430fe427a", "msp430fg4250",
2650 "msp430fg4260", "msp430fg4270", "msp430fg437",
2651 "msp430fg438", "msp430fg439", "msp430fg477",
2652 "msp430fg478", "msp430fg479", "msp430fr2032",
2653 "msp430fr2033", "msp430fr4131", "msp430fr4132",
2654 "msp430fr4133", "msp430fw423", "msp430fw425",
2655 "msp430fw427", "msp430fw428", "msp430fw429",
2656 "msp430g2001", "msp430g2101", "msp430g2102",
2657 "msp430g2111", "msp430g2112", "msp430g2113",
2658 "msp430g2121", "msp430g2131", "msp430g2132",
2659 "msp430g2152", "msp430g2153", "msp430g2201",
2660 "msp430g2202", "msp430g2203", "msp430g2210",
2661 "msp430g2211", "msp430g2212", "msp430g2213",
2662 "msp430g2221", "msp430g2230", "msp430g2231",
2663 "msp430g2232", "msp430g2233", "msp430g2252",
2664 "msp430g2253", "msp430g2302", "msp430g2303",
2665 "msp430g2312", "msp430g2313", "msp430g2332",
2666 "msp430g2333", "msp430g2352", "msp430g2353",
2667 "msp430g2402", "msp430g2403", "msp430g2412",
2668 "msp430g2413", "msp430g2432", "msp430g2433",
2669 "msp430g2444", "msp430g2452", "msp430g2453",
2670 "msp430g2513", "msp430g2533", "msp430g2544",
2671 "msp430g2553", "msp430g2744", "msp430g2755",
2672 "msp430g2855", "msp430g2955", "msp430l092",
2673 "msp430p112", "msp430p313", "msp430p315",
2674 "msp430p315s", "msp430p325", "msp430tch5e"
2676 static const char * cached_match
= NULL
;
2677 static bool cached_result
;
2680 if (msp430_hwmult_type
== NONE
)
2683 if (target_mcu
== NULL
|| msp430_hwmult_type
!= AUTO
)
2686 if (target_mcu
== cached_match
)
2687 return cached_result
;
2689 cached_match
= target_mcu
;
2690 for (i
= ARRAY_SIZE (known_nomult_mcus
); i
--;)
2691 if (strcasecmp (target_mcu
, known_nomult_mcus
[i
]) == 0)
2692 return cached_result
= true;
2694 return cached_result
= false;
2697 /* This function does the same as the default, but it will replace GCC
2698 function names with the MSPABI-specified ones. */
2701 msp430_output_labelref (FILE *file
, const char *name
)
2705 for (i
= 0; helper_function_name_mappings
[i
].gcc_name
; i
++)
2706 if (strcmp (helper_function_name_mappings
[i
].gcc_name
, name
) == 0)
2708 name
= helper_function_name_mappings
[i
].ti_name
;
2712 /* If we have been given a specific MCU name then we may be
2713 able to make use of its hardware multiply capabilities. */
2714 if (msp430_hwmult_type
!= NONE
)
2716 if (strcmp ("__mspabi_mpyi", name
) == 0)
2718 if (msp430_use_f5_series_hwmult ())
2719 name
= "__mulhi2_f5";
2720 else if (! msp430_no_hwmult ())
2723 else if (strcmp ("__mspabi_mpyl", name
) == 0)
2725 if (msp430_use_f5_series_hwmult ())
2726 name
= "__mulsi2_f5";
2727 else if (use_32bit_hwmult ())
2728 name
= "__mulsi2_hw32";
2729 else if (! msp430_no_hwmult ())
2737 /* Common code for msp430_print_operand... */
2740 msp430_print_operand_raw (FILE * file
, rtx op
)
2744 switch (GET_CODE (op
))
2747 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
2753 fprintf (file
, "%#" HOST_WIDE_INT_PRINT
"x", i
);
2755 fprintf (file
, "%" HOST_WIDE_INT_PRINT
"d", i
);
2763 output_addr_const (file
, op
);
2767 print_rtl (file
, op
);
2772 #undef TARGET_PRINT_OPERAND_ADDRESS
2773 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
2775 /* Output to stdio stream FILE the assembler syntax for an
2776 instruction operand that is a memory reference whose address
2780 msp430_print_operand_addr (FILE * file
, rtx addr
)
2782 switch (GET_CODE (addr
))
2785 msp430_print_operand_raw (file
, XEXP (addr
, 1));
2786 gcc_assert (REG_P (XEXP (addr
, 0)));
2787 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
2791 fprintf (file
, "@");
2798 fprintf (file
, "&");
2805 msp430_print_operand_raw (file
, addr
);
2808 #undef TARGET_PRINT_OPERAND
2809 #define TARGET_PRINT_OPERAND msp430_print_operand
2811 /* A low 16-bits of int/lower of register pair
2812 B high 16-bits of int/higher of register pair
2813 C bits 32-47 of a 64-bit value/reg 3 of a DImode value
2814 D bits 48-63 of a 64-bit value/reg 4 of a DImode value
2815 H like %B (for backwards compatibility)
2817 J an integer without a # prefix
2818 L like %A (for backwards compatibility)
2819 O offset of the top of the stack
2820 Q like X but generates an A postfix
2821 R inverse of condition code, unsigned.
2822 X X instruction postfix in large mode
2825 b .B or .W or .A, depending upon the mode
2827 r inverse of condition code
2828 x like X but only for pointers. */
2831 msp430_print_operand (FILE * file
, rtx op
, int letter
)
2835 /* We can't use c, n, a, or l. */
2839 gcc_assert (CONST_INT_P (op
));
2840 /* Print the constant value, less one. */
2841 fprintf (file
, "#%ld", INTVAL (op
) - 1);
2844 gcc_assert (CONST_INT_P (op
));
2845 /* Print the constant value, less four. */
2846 fprintf (file
, "#%ld", INTVAL (op
) - 4);
2849 if (GET_CODE (op
) == CONST_INT
)
2851 /* Inverse of constants */
2852 int i
= INTVAL (op
);
2853 fprintf (file
, "%d", ~i
);
2858 case 'r': /* Conditional jump where the condition is reversed. */
2859 switch (GET_CODE (op
))
2861 case EQ
: fprintf (file
, "NE"); break;
2862 case NE
: fprintf (file
, "EQ"); break;
2863 case GEU
: fprintf (file
, "LO"); break;
2864 case LTU
: fprintf (file
, "HS"); break;
2865 case GE
: fprintf (file
, "L"); break;
2866 case LT
: fprintf (file
, "GE"); break;
2867 /* Assume these have reversed operands. */
2868 case GTU
: fprintf (file
, "HS"); break;
2869 case LEU
: fprintf (file
, "LO"); break;
2870 case GT
: fprintf (file
, "GE"); break;
2871 case LE
: fprintf (file
, "L"); break;
2873 msp430_print_operand_raw (file
, op
);
2877 case 'R': /* Conditional jump where the operands are reversed. */
2878 switch (GET_CODE (op
))
2880 case GTU
: fprintf (file
, "LO"); break;
2881 case LEU
: fprintf (file
, "HS"); break;
2882 case GT
: fprintf (file
, "L"); break;
2883 case LE
: fprintf (file
, "GE"); break;
2885 msp430_print_operand_raw (file
, op
);
2889 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
2890 gcc_assert (CONST_INT_P (op
));
2891 fprintf (file
, "#%d", 1 << INTVAL (op
));
2894 switch (GET_MODE (op
))
2896 case QImode
: fprintf (file
, ".B"); return;
2897 case HImode
: fprintf (file
, ".W"); return;
2898 case PSImode
: fprintf (file
, ".A"); return;
2899 case SImode
: fprintf (file
, ".A"); return;
2904 case 'L': /* Low half. */
2905 switch (GET_CODE (op
))
2908 op
= adjust_address (op
, Pmode
, 0);
2913 op
= GEN_INT (INTVAL (op
) & 0xffff);
2917 /* If you get here, figure out a test case :-) */
2922 case 'H': /* high half */
2923 switch (GET_CODE (op
))
2926 op
= adjust_address (op
, Pmode
, 2);
2929 op
= gen_rtx_REG (Pmode
, REGNO (op
) + 1);
2932 op
= GEN_INT (INTVAL (op
) >> 16);
2936 /* If you get here, figure out a test case :-) */
2941 switch (GET_CODE (op
))
2944 op
= adjust_address (op
, Pmode
, 3);
2947 op
= gen_rtx_REG (Pmode
, REGNO (op
) + 2);
2950 op
= GEN_INT ((long long) INTVAL (op
) >> 32);
2954 /* If you get here, figure out a test case :-) */
2959 switch (GET_CODE (op
))
2962 op
= adjust_address (op
, Pmode
, 4);
2965 op
= gen_rtx_REG (Pmode
, REGNO (op
) + 3);
2968 op
= GEN_INT ((long long) INTVAL (op
) >> 48);
2972 /* If you get here, figure out a test case :-) */
2978 /* This is used to turn, for example, an ADD opcode into an ADDX
2979 opcode when we're using 20-bit addresses. */
2980 if (TARGET_LARGE
|| GET_MODE (op
) == PSImode
)
2981 fprintf (file
, "X");
2982 /* We don't care which operand we use, but we want 'X' in the MD
2983 file, so we do it this way. */
2987 /* Similarly, but only for PSImodes. BIC, for example, needs this. */
2988 if (GET_MODE (op
) == PSImode
)
2989 fprintf (file
, "X");
2993 /* Likewise, for BR -> BRA. */
2995 fprintf (file
, "A");
2999 /* Computes the offset to the top of the stack for the current frame.
3000 This has to be done here rather than in, say, msp430_expand_builtin()
3001 because builtins are expanded before the frame layout is determined. */
3002 fprintf (file
, "%d",
3003 msp430_initial_elimination_offset (ARG_POINTER_REGNUM
, STACK_POINTER_REGNUM
)
3004 - (TARGET_LARGE
? 4 : 2));
3008 gcc_assert (GET_CODE (op
) == CONST_INT
);
3012 output_operand_lossage ("invalid operand prefix");
3016 switch (GET_CODE (op
))
3019 msp430_print_operand_raw (file
, op
);
3023 addr
= XEXP (op
, 0);
3024 msp430_print_operand_addr (file
, addr
);
3028 if (GET_CODE (XEXP (op
, 0)) == ZERO_EXTRACT
)
3031 switch (INTVAL (XEXP (op
, 2)))
3034 fprintf (file
, "#lo (");
3035 msp430_print_operand_raw (file
, XEXP (op
, 0));
3036 fprintf (file
, ")");
3040 fprintf (file
, "#hi (");
3041 msp430_print_operand_raw (file
, XEXP (op
, 0));
3042 fprintf (file
, ")");
3046 output_operand_lossage ("invalid zero extract");
3056 fprintf (file
, "#");
3057 msp430_print_operand_raw (file
, op
);
3060 case EQ
: fprintf (file
, "EQ"); break;
3061 case NE
: fprintf (file
, "NE"); break;
3062 case GEU
: fprintf (file
, "HS"); break;
3063 case LTU
: fprintf (file
, "LO"); break;
3064 case GE
: fprintf (file
, "GE"); break;
3065 case LT
: fprintf (file
, "L"); break;
3068 print_rtl (file
, op
);
3077 msp430_return_addr_rtx (int count
)
3083 ra_size
= TARGET_LARGE
? 4 : 2;
3084 if (crtl
->args
.pretend_args_size
)
3087 return gen_rtx_MEM (Pmode
, gen_rtx_PLUS (Pmode
, arg_pointer_rtx
, GEN_INT (- ra_size
)));
3091 msp430_incoming_return_addr_rtx (void)
3093 return gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
3096 /* Instruction generation stuff. */
3098 /* Generate a sequence of instructions to sign-extend an HI
3099 value into an SI value. Handles the tricky case where
3100 we are overwriting the destination. */
3103 msp430x_extendhisi (rtx
* operands
)
3105 if (REGNO (operands
[0]) == REGNO (operands
[1]))
3106 /* Low word of dest == source word. */
3107 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */
3110 /* Note: This sequence is approximately the same length as invoking a helper
3111 function to perform the sign-extension, as in:
3115 CALL __mspabi_srai_15
3118 but this version does not involve any function calls or using argument
3119 registers, so it reduces register pressure. */
3120 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */
3122 if (REGNO (operands
[0]) + 1 == REGNO (operands
[1]))
3123 /* High word of dest == source word. */
3124 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
3126 /* No overlap between dest and source. */
3127 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */
3130 /* Likewise for logical right shifts. */
3132 msp430x_logical_shift_right (rtx amount
)
3134 /* The MSP430X's logical right shift instruction - RRUM - does
3135 not use an extension word, so we cannot encode a repeat count.
3136 Try various alternatives to work around this. If the count
3137 is in a register we are stuck, hence the assert. */
3138 gcc_assert (CONST_INT_P (amount
));
3140 if (INTVAL (amount
) <= 0
3141 || INTVAL (amount
) >= 16)
3142 return "# nop logical shift.";
3144 if (INTVAL (amount
) > 0
3145 && INTVAL (amount
) < 5)
3146 return "rrum.w\t%2, %0"; /* Two bytes. */
3148 if (INTVAL (amount
) > 4
3149 && INTVAL (amount
) < 9)
3150 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
3152 /* First we logically shift right by one. Now we know
3153 that the top bit is zero and we can use the arithmetic
3154 right shift instruction to perform the rest of the shift. */
3155 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */
3158 struct gcc_target targetm
= TARGET_INITIALIZER
;
3160 #include "gt-msp430.h"