1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2025 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define IN_TARGET_CODE 1
25 #include "coretypes.h"
30 #include "stringpool.h"
32 #include "gimple-expr.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
46 #include "langhooks.h"
49 #include "msp430-devices.h"
52 #include "insn-config.h"
53 #include "insn-attr.h"
56 /* This file should be included last. */
57 #include "target-def.h"
60 static void msp430_compute_frame_info (void);
61 static bool msp430_use_16bit_hwmult (void);
62 static bool msp430_use_32bit_hwmult (void);
63 static bool use_helper_for_const_shift (machine_mode mode
, HOST_WIDE_INT amt
);
67 /* Run-time Target Specification. */
71 struct GTY(()) machine_function
73 /* If set, the rest of the fields have been computed. */
75 /* Which registers need to be saved in the pro/epilogue. */
76 int need_to_save
[FIRST_PSEUDO_REGISTER
];
78 /* These fields describe the frame layout... */
80 /* 2/4 bytes for saved PC */
84 int framesize_outgoing
;
88 /* How much we adjust the stack when returning from an exception
93 /* This is our init_machine_status, as set in
94 msp430_option_override. */
95 static struct machine_function
*
96 msp430_init_machine_status (void)
98 struct machine_function
*m
;
100 m
= ggc_cleared_alloc
<machine_function
> ();
105 #undef TARGET_OPTION_OVERRIDE
106 #define TARGET_OPTION_OVERRIDE msp430_option_override
108 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
109 If a specific MCU has not been selected then return a generic symbol
113 msp430_mcu_name (void)
117 msp430_extract_mcu_data (target_mcu
);
119 unsigned int start_upper
;
120 unsigned int end_upper
;
121 static char mcu_name
[64];
123 /* The 'i' in the device name symbol for msp430i* devices must be lower
124 case, to match the expected symbol in msp430.h. */
125 if (startswith (target_mcu
, "msp430i"))
127 snprintf (mcu_name
, sizeof (mcu_name
) - 1, "__MSP430i%s__",
133 snprintf (mcu_name
, sizeof (mcu_name
) - 1, "__%s__", target_mcu
);
136 end_upper
= strlen (mcu_name
) - 2;
137 for (i
= start_upper
; i
< end_upper
; i
++)
138 mcu_name
[i
] = TOUPPER (mcu_name
[i
]);
142 return msp430x
? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
146 hwmult_name (unsigned int val
)
150 case 0: return "none";
151 case 1: return "16-bit";
152 case 2: return "16-bit";
153 case 4: return "32-bit";
154 case 8: return "32-bit (5xx)";
155 default: gcc_unreachable ();
160 msp430_option_override (void)
162 /* The MSP430 architecture can safely dereference a NULL pointer. In fact,
163 there are memory mapped registers there. */
164 flag_delete_null_pointer_checks
= 0;
166 init_machine_status
= msp430_init_machine_status
;
168 msp430x
= target_cpu
>= MSP430_CPU_MSP430X_DEFAULT
;
172 msp430_extract_mcu_data (target_mcu
);
174 if (extracted_mcu_data
.name
!= NULL
)
176 bool xisa
= extracted_mcu_data
.revision
>= 1;
180 if (target_cpu
!= MSP430_CPU_MSP430X_DEFAULT
&& msp430x
!= xisa
)
181 warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
183 target_mcu
, xisa
? "430X" : "430",
184 msp430x
? "430X" : "430");
186 if (extracted_mcu_data
.hwmpy
== 0
187 && msp430_hwmult_type
!= MSP430_HWMULT_AUTO
188 && msp430_hwmult_type
!= MSP430_HWMULT_NONE
)
189 warning (0, "MCU %qs does not have hardware multiply "
190 "support, but %<-mhwmult%> is set to %s",
192 msp430_hwmult_type
== MSP430_HWMULT_SMALL
? "16-bit"
193 : msp430_hwmult_type
== MSP430_HWMULT_LARGE
194 ? "32-bit" : "f5series");
195 else if (msp430_hwmult_type
== MSP430_HWMULT_SMALL
196 && extracted_mcu_data
.hwmpy
!= 1
197 && extracted_mcu_data
.hwmpy
!= 2)
198 warning (0, "MCU %qs supports %s hardware multiply, "
199 "but %<-mhwmult%> is set to 16-bit",
200 target_mcu
, hwmult_name (extracted_mcu_data
.hwmpy
));
201 else if (msp430_hwmult_type
== MSP430_HWMULT_LARGE
202 && extracted_mcu_data
.hwmpy
!= 4)
203 warning (0, "MCU %qs supports %s hardware multiply, "
204 "but %<-mhwmult%> is set to 32-bit",
205 target_mcu
, hwmult_name (extracted_mcu_data
.hwmpy
));
206 else if (msp430_hwmult_type
== MSP430_HWMULT_F5SERIES
207 && extracted_mcu_data
.hwmpy
!= 8)
208 warning (0, "MCU %qs supports %s hardware multiply, "
209 "but %<-mhwmult%> is set to f5series",
210 target_mcu
, hwmult_name (extracted_mcu_data
.hwmpy
));
212 /* Only override the default setting with the extracted ISA value if
213 the user has not passed -mcpu=. */
214 if (target_cpu
== MSP430_CPU_MSP430X_DEFAULT
)
219 if (msp430_hwmult_type
== MSP430_HWMULT_AUTO
)
223 if (target_cpu
== MSP430_CPU_MSP430X_DEFAULT
)
225 "unrecognized MCU name %qs, assuming that it is "
226 "just a MSP430X with no hardware multiply; "
227 "use the %<-mcpu%> and %<-mhwmult%> options to "
228 "set these explicitly",
232 "unrecognized MCU name %qs, assuming that it "
233 "has no hardware multiply; use the %<-mhwmult%> "
234 "option to set this explicitly",
238 msp430_hwmult_type
= MSP430_HWMULT_NONE
;
240 else if (target_cpu
== MSP430_CPU_MSP430X_DEFAULT
)
244 "unrecognized MCU name %qs, assuming that it just "
245 "supports the MSP430X ISA; use the %<-mcpu%> option "
246 "to set the ISA explicitly",
249 else if (msp430_warn_mcu
)
250 warning (0, "Unrecognized MCU name %qs.", target_mcu
);
254 if (TARGET_LARGE
&& !msp430x
)
255 error ("%<-mlarge%> requires a 430X-compatible %<-mmcu=%>");
257 if (!TARGET_LARGE
&& msp430_code_region
== MSP430_REGION_EITHER
)
258 error ("%<-mcode-region=either%> requires the large memory model "
260 else if (!TARGET_LARGE
&& msp430_code_region
== MSP430_REGION_UPPER
)
261 error ("%<-mcode-region=upper%> requires the large memory model "
264 if (!TARGET_LARGE
&& msp430_data_region
== MSP430_REGION_EITHER
)
265 error ("%<-mdata-region=either%> requires the large memory model "
267 else if (!TARGET_LARGE
&& msp430_data_region
== MSP430_REGION_UPPER
)
268 error ("%<-mdata-region=upper%> requires the large memory model "
271 if (flag_exceptions
|| flag_non_call_exceptions
272 || flag_unwind_tables
|| flag_asynchronous_unwind_tables
)
273 flag_omit_frame_pointer
= false;
275 flag_omit_frame_pointer
= true;
277 /* This is a hack to work around a problem with the newlib build
278 mechanism. Newlib always appends CFLAGS to the end of the GCC
279 command line and always sets -O2 in CFLAGS. Thus it is not
280 possible to build newlib with -Os enabled. Until now... */
281 if (TARGET_OPT_SPACE
&& optimize
< 3)
284 #if !DEFAULT_USE_CXA_ATEXIT
285 /* For some configurations, we use atexit () instead of __cxa_atexit () by
286 default to save on code size and remove the declaration of __dso_handle
287 from the CRT library.
288 Configuring GCC with --enable-__cxa-atexit re-enables it by defining
289 DEFAULT_USE_CXA_ATEXIT to 1. */
290 if (flag_use_cxa_atexit
)
291 error ("%<-fuse-cxa-atexit%> is not supported for msp430-elf");
294 #ifndef HAVE_NEWLIB_NANO_FORMATTED_IO
295 if (TARGET_TINY_PRINTF
)
296 error ("GCC must be configured with %<--enable-newlib-nano-formatted-io%> "
297 "to use %<-mtiny-printf%>");
301 #undef TARGET_SCALAR_MODE_SUPPORTED_P
302 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
305 msp430_scalar_mode_supported_p (scalar_mode m
)
307 if (m
== PSImode
&& msp430x
)
313 return default_scalar_mode_supported_p (m
);
320 #undef TARGET_MS_BITFIELD_LAYOUT_P
321 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
324 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED
)
333 #undef TARGET_HARD_REGNO_NREGS
334 #define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs
337 msp430_hard_regno_nregs (unsigned int, machine_mode mode
)
339 if (mode
== PSImode
&& msp430x
)
341 if (mode
== CPSImode
&& msp430x
)
343 return ((GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1)
347 /* subreg_get_info correctly handles PSImode registers, so defining
348 HARD_REGNO_NREGS_HAS_PADDING and HARD_REGNO_NREGS_WITH_PADDING
351 #undef TARGET_HARD_REGNO_MODE_OK
352 #define TARGET_HARD_REGNO_MODE_OK msp430_hard_regno_mode_ok
355 msp430_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
357 return regno
<= (ARG_POINTER_REGNUM
358 - (unsigned int) msp430_hard_regno_nregs (regno
, mode
));
361 #undef TARGET_MODES_TIEABLE_P
362 #define TARGET_MODES_TIEABLE_P msp430_modes_tieable_p
365 msp430_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
367 if ((mode1
== PSImode
|| mode2
== SImode
)
368 || (mode1
== SImode
|| mode2
== PSImode
))
371 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
372 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
373 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
374 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
377 #undef TARGET_FRAME_POINTER_REQUIRED
378 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
381 msp430_frame_pointer_required (void)
386 #undef TARGET_CAN_ELIMINATE
387 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
390 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED
,
391 const int to_reg ATTRIBUTE_UNUSED
)
396 /* Implements INITIAL_ELIMINATION_OFFSET. */
398 msp430_initial_elimination_offset (int from
, int to
)
400 int rv
= 0; /* As if arg to arg. */
402 msp430_compute_frame_info ();
406 case STACK_POINTER_REGNUM
:
407 rv
+= cfun
->machine
->framesize_outgoing
;
408 rv
+= cfun
->machine
->framesize_locals
;
410 case FRAME_POINTER_REGNUM
:
411 rv
+= cfun
->machine
->framesize_regs
;
412 /* Allow for the saved return address. */
413 rv
+= (TARGET_LARGE
? 4 : 2);
414 /* NB/ No need to allow for crtl->args.pretend_args_size.
415 GCC does that for us. */
423 case FRAME_POINTER_REGNUM
:
424 /* Allow for the fall through above. */
425 rv
-= (TARGET_LARGE
? 4 : 2);
426 rv
-= cfun
->machine
->framesize_regs
;
427 case ARG_POINTER_REGNUM
:
436 /* Named Address Space support */
439 /* Return the appropriate mode for a named address pointer. */
440 #undef TARGET_ADDR_SPACE_POINTER_MODE
441 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
442 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
443 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
445 static scalar_int_mode
446 msp430_addr_space_pointer_mode (addr_space_t addrspace
)
451 case ADDR_SPACE_GENERIC
:
453 case ADDR_SPACE_NEAR
:
460 /* Function pointers are stored in unwind_word sized
461 variables, so make sure that unwind_word is big enough. */
462 #undef TARGET_UNWIND_WORD_MODE
463 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
465 static scalar_int_mode
466 msp430_unwind_word_mode (void)
468 /* This needs to match msp430_init_dwarf_reg_sizes_extra (below). */
469 return msp430x
? PSImode
: HImode
;
472 /* Determine if one named address space is a subset of another. */
473 #undef TARGET_ADDR_SPACE_SUBSET_P
474 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
476 msp430_addr_space_subset_p (addr_space_t subset
, addr_space_t superset
)
478 if (subset
== superset
)
481 return (subset
!= ADDR_SPACE_FAR
&& superset
== ADDR_SPACE_FAR
);
484 #undef TARGET_ADDR_SPACE_CONVERT
485 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
486 /* Convert from one address space to another. */
488 msp430_addr_space_convert (rtx op
, tree from_type
, tree to_type
)
490 addr_space_t from_as
= TYPE_ADDR_SPACE (TREE_TYPE (from_type
));
491 addr_space_t to_as
= TYPE_ADDR_SPACE (TREE_TYPE (to_type
));
494 if (to_as
!= ADDR_SPACE_FAR
&& from_as
== ADDR_SPACE_FAR
)
496 /* This is unpredictable, as we're truncating off usable address
500 return gen_rtx_CONST (HImode
, op
);
502 result
= gen_reg_rtx (HImode
);
503 emit_insn (gen_truncpsihi2 (result
, op
));
506 else if (to_as
== ADDR_SPACE_FAR
&& from_as
!= ADDR_SPACE_FAR
)
508 /* This always works. */
511 return gen_rtx_CONST (PSImode
, op
);
513 result
= gen_reg_rtx (PSImode
);
514 emit_insn (gen_zero_extendhipsi2 (result
, op
));
521 /* Stack Layout and Calling Conventions. */
523 /* For each function, we list the gcc version and the TI version on
524 each line, where we're converting the function names. */
525 static char const * const special_convention_function_names
[] =
527 "__muldi3", "__mspabi_mpyll",
528 "__udivdi3", "__mspabi_divull",
529 "__umoddi3", "__mspabi_remull",
530 "__divdi3", "__mspabi_divlli",
531 "__moddi3", "__mspabi_remlli",
535 "__adddf3", "__mspabi_addd",
536 "__subdf3", "__mspabi_subd",
537 "__muldf3", "__mspabi_mpyd",
538 "__divdf3", "__mspabi_divd",
543 /* TRUE if the function passed is a "speical" function. Special
544 functions pass two DImode parameters in registers. */
546 msp430_special_register_convention_p (const char *name
)
550 for (i
= 0; special_convention_function_names
[i
]; i
++)
551 if (!strcmp (name
, special_convention_function_names
[i
]))
557 #undef TARGET_FUNCTION_VALUE_REGNO_P
558 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
561 msp430_function_value_regno_p (unsigned int regno
)
567 #undef TARGET_FUNCTION_VALUE
568 #define TARGET_FUNCTION_VALUE msp430_function_value
571 msp430_function_value (const_tree ret_type
,
572 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
573 bool outgoing ATTRIBUTE_UNUSED
)
575 return gen_rtx_REG (TYPE_MODE (ret_type
), 12);
578 #undef TARGET_LIBCALL_VALUE
579 #define TARGET_LIBCALL_VALUE msp430_libcall_value
582 msp430_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
584 return gen_rtx_REG (mode
, 12);
587 /* Implements INIT_CUMULATIVE_ARGS. */
589 msp430_init_cumulative_args (CUMULATIVE_ARGS
*ca
,
590 tree fntype ATTRIBUTE_UNUSED
,
591 rtx libname ATTRIBUTE_UNUSED
,
592 tree fndecl ATTRIBUTE_UNUSED
,
593 int n_named_args ATTRIBUTE_UNUSED
)
596 memset (ca
, 0, sizeof(*ca
));
601 fname
= IDENTIFIER_POINTER (DECL_NAME (fndecl
));
603 fname
= XSTR (libname
, 0);
607 if (fname
&& msp430_special_register_convention_p (fname
))
611 /* Helper function for argument passing; this function is the common
612 code that determines where an argument will be passed. */
614 msp430_evaluate_arg (cumulative_args_t cap
,
616 const_tree type ATTRIBUTE_UNUSED
,
619 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
620 int nregs
= GET_MODE_SIZE (mode
);
632 nregs
= (nregs
+ 1) / 2;
636 /* Function is passed two DImode operands, in R8:R11 and
646 for (i
= 0; i
< 4; i
++)
647 if (!ca
->reg_used
[i
])
650 ca
->start_reg
= CA_FIRST_REG
+ i
;
655 for (i
= 0; i
< 3; i
++)
656 if (!ca
->reg_used
[i
] && !ca
->reg_used
[i
+ 1])
659 ca
->start_reg
= CA_FIRST_REG
+ i
;
662 if (!ca
->reg_used
[3] && ca
->can_split
)
666 ca
->start_reg
= CA_FIRST_REG
+ 3;
679 ca
->start_reg
= CA_FIRST_REG
;
686 #undef TARGET_PROMOTE_PROTOTYPES
687 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
690 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED
)
695 #undef TARGET_FUNCTION_ARG
696 #define TARGET_FUNCTION_ARG msp430_function_arg
699 msp430_function_arg (cumulative_args_t cap
,
700 const function_arg_info
&arg
)
702 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
704 msp430_evaluate_arg (cap
, arg
.mode
, arg
.type
, arg
.named
);
707 return gen_rtx_REG (arg
.mode
, ca
->start_reg
);
712 #undef TARGET_ARG_PARTIAL_BYTES
713 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
716 msp430_arg_partial_bytes (cumulative_args_t cap
, const function_arg_info
&arg
)
718 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
720 msp430_evaluate_arg (cap
, arg
.mode
, arg
.type
, arg
.named
);
722 if (ca
->reg_count
&& ca
->mem_count
)
723 return ca
->reg_count
* UNITS_PER_WORD
;
728 #undef TARGET_PASS_BY_REFERENCE
729 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
732 msp430_pass_by_reference (cumulative_args_t
, const function_arg_info
&arg
)
734 return (arg
.mode
== BLKmode
735 || (arg
.type
&& TREE_CODE (arg
.type
) == RECORD_TYPE
)
736 || (arg
.type
&& TREE_CODE (arg
.type
) == UNION_TYPE
));
739 #undef TARGET_CALLEE_COPIES
740 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_arg_info_true
742 #undef TARGET_FUNCTION_ARG_ADVANCE
743 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
746 msp430_function_arg_advance (cumulative_args_t cap
,
747 const function_arg_info
&arg
)
749 CUMULATIVE_ARGS
*ca
= get_cumulative_args (cap
);
752 msp430_evaluate_arg (cap
, arg
.mode
, arg
.type
, arg
.named
);
754 if (ca
->start_reg
>= CA_FIRST_REG
)
755 for (i
= 0; i
< ca
->reg_count
; i
++)
756 ca
->reg_used
[i
+ ca
->start_reg
- CA_FIRST_REG
] = 1;
761 #undef TARGET_FUNCTION_ARG_BOUNDARY
762 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
765 msp430_function_arg_boundary (machine_mode mode
, const_tree type
)
768 && int_size_in_bytes (type
) > 1)
770 if (GET_MODE_BITSIZE (mode
) > 8)
775 #undef TARGET_RETURN_IN_MEMORY
776 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
779 msp430_return_in_memory (const_tree ret_type
,
780 const_tree fntype ATTRIBUTE_UNUSED
)
782 machine_mode mode
= TYPE_MODE (ret_type
);
785 || (fntype
&& TREE_CODE (TREE_TYPE (fntype
)) == RECORD_TYPE
)
786 || (fntype
&& TREE_CODE (TREE_TYPE (fntype
)) == UNION_TYPE
))
789 if (GET_MODE_SIZE (mode
) > 8)
795 #undef TARGET_GET_RAW_ARG_MODE
796 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
798 static fixed_size_mode
799 msp430_get_raw_arg_mode (int regno
)
801 return as_a
<fixed_size_mode
> (regno
== ARG_POINTER_REGNUM
805 #undef TARGET_GET_RAW_RESULT_MODE
806 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
808 static fixed_size_mode
809 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED
)
814 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
815 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
817 #include "gimplify.h"
820 msp430_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
823 tree addr
, t
, type_size
, rounded_size
, valist_tmp
;
824 unsigned HOST_WIDE_INT align
, boundary
;
827 indirect
= pass_va_arg_by_reference (type
);
829 type
= build_pointer_type (type
);
831 align
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
832 boundary
= targetm
.calls
.function_arg_boundary (TYPE_MODE (type
), type
);
834 /* When we align parameter on stack for caller, if the parameter
835 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
836 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
838 if (boundary
> MAX_SUPPORTED_STACK_ALIGNMENT
)
839 boundary
= MAX_SUPPORTED_STACK_ALIGNMENT
;
841 boundary
/= BITS_PER_UNIT
;
843 /* Hoist the valist value into a temporary for the moment. */
844 valist_tmp
= get_initialized_tmp_var (valist
, pre_p
, NULL
);
846 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
847 requires greater alignment, we must perform dynamic alignment. */
849 && !integer_zerop (TYPE_SIZE (type
)))
851 /* FIXME: This is where this function diverts from targhooks.cc:
852 std_gimplify_va_arg_expr(). It works, but I do not know why... */
853 if (! POINTER_TYPE_P (type
))
855 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
856 fold_build_pointer_plus_hwi (valist_tmp
, boundary
- 1));
857 gimplify_and_add (t
, pre_p
);
859 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist_tmp
,
860 fold_build2 (BIT_AND_EXPR
, TREE_TYPE (valist
),
862 build_int_cst (TREE_TYPE (valist
),
864 gimplify_and_add (t
, pre_p
);
870 /* If the actual alignment is less than the alignment of the type,
871 adjust the type accordingly so that we don't assume strict alignment
872 when dereferencing the pointer. */
873 boundary
*= BITS_PER_UNIT
;
874 if (boundary
< TYPE_ALIGN (type
))
876 type
= build_variant_type_copy (type
);
877 SET_TYPE_ALIGN (type
, boundary
);
880 /* Compute the rounded size of the type. */
881 type_size
= size_in_bytes (type
);
882 rounded_size
= round_up (type_size
, align
);
884 /* Reduce rounded_size so it's sharable with the postqueue. */
885 gimplify_expr (&rounded_size
, pre_p
, post_p
, is_gimple_val
, fb_rvalue
);
890 /* Compute new value for AP. */
891 t
= fold_build_pointer_plus (valist_tmp
, rounded_size
);
892 t
= build2 (MODIFY_EXPR
, TREE_TYPE (valist
), valist
, t
);
893 gimplify_and_add (t
, pre_p
);
895 addr
= fold_convert (build_pointer_type (type
), addr
);
898 addr
= build_va_arg_indirect_ref (addr
);
900 addr
= build_va_arg_indirect_ref (addr
);
906 #define TARGET_LRA_P hook_bool_void_false
908 /* Addressing Modes */
910 #undef TARGET_LEGITIMATE_ADDRESS_P
911 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
914 reg_ok_for_addr (rtx r
, bool strict
)
918 if (strict
&& rn
>= FIRST_PSEUDO_REGISTER
)
919 rn
= reg_renumber
[rn
];
920 if (strict
&& 0 <= rn
&& rn
< FIRST_PSEUDO_REGISTER
)
928 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED
,
929 rtx x ATTRIBUTE_UNUSED
,
930 bool strict ATTRIBUTE_UNUSED
,
931 code_helper
= ERROR_MARK
)
933 switch (GET_CODE (x
))
940 if (REG_P (XEXP (x
, 0)))
942 if (GET_MODE (x
) != GET_MODE (XEXP (x
, 0)))
944 if (!reg_ok_for_addr (XEXP (x
, 0), strict
))
946 if (GET_CODE (x
) == POST_INC
)
947 /* At this point, if the original rtx was a post_inc, we don't have
948 anything further to check. */
950 switch (GET_CODE (XEXP (x
, 1)))
963 if (!reg_ok_for_addr (x
, strict
))
976 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
977 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
978 msp430_addr_space_legitimate_address_p
981 msp430_addr_space_legitimate_address_p (machine_mode mode
,
984 addr_space_t as ATTRIBUTE_UNUSED
,
985 code_helper ch
= ERROR_MARK
)
987 return msp430_legitimate_address_p (mode
, x
, strict
, ch
);
990 #undef TARGET_ASM_INTEGER
991 #define TARGET_ASM_INTEGER msp430_asm_integer
993 msp430_asm_integer (rtx x
, unsigned int size
, int aligned_p
)
995 int c
= GET_CODE (x
);
997 if (size
== 3 && GET_MODE (x
) == PSImode
)
1003 if (c
== SYMBOL_REF
|| c
== CONST
|| c
== LABEL_REF
|| c
== CONST_INT
1004 || c
== PLUS
|| c
== MINUS
)
1006 fprintf (asm_out_file
, "\t.long\t");
1007 output_addr_const (asm_out_file
, x
);
1008 fputc ('\n', asm_out_file
);
1013 return default_assemble_integer (x
, size
, aligned_p
);
1016 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1017 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
1019 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED
, rtx x
)
1025 #undef TARGET_LEGITIMATE_CONSTANT_P
1026 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1029 msp430_legitimate_constant (machine_mode mode
, rtx x
)
1031 return ! CONST_INT_P (x
)
1033 /* GCC does not know the width of the PSImode, so make
1034 sure that it does not try to use a constant value that
1036 || (INTVAL (x
) < (1 << 20)
1037 && INTVAL (x
) >= (HOST_WIDE_INT
)(HOST_WIDE_INT_M1U
<< 20));
1041 /* Describing Relative Costs of Operations
1042 To model the cost of an instruction, use the number of cycles when
1043 optimizing for speed, and the number of words when optimizing for size.
1044 The cheapest instruction will execute in one cycle and cost one word.
1045 The cycle and size costs correspond to 430 ISA instructions, not 430X
1046 instructions or 430X "address" instructions. The relative costs of 430X
1047 instructions is accurately modeled with the 430 costs. The relative costs
1048 of some "address" instructions can differ, but these are not yet handled.
1049 Adding support for this could improve performance/code size. */
1051 struct single_op_cost
1054 /* Indirect register (@Rn) or indirect autoincrement (@Rn+). */
1059 static const struct single_op_cost cycle_cost_single_op
=
1064 static const struct single_op_cost size_cost_single_op
=
1069 /* When the destination of an insn is memory, the cost is always the same
1070 regardless of whether that memory is accessed using indirect register,
1071 indexed or absolute addressing.
1072 When the source operand is memory, indirect register and post-increment have
1073 the same cost, which is lower than indexed and absolute, which also have
1075 struct double_op_cost
1077 /* Source operand is a register. */
1082 /* Source operand is memory, using indirect register (@Rn) or indirect
1083 autoincrement (@Rn+) addressing modes. */
1088 /* Source operand is an immediate. */
1093 /* Source operand is memory, using indexed (x(Rn)) or absolute (&ADDR)
1094 addressing modes. */
1100 /* These structures describe the cost of MOV, BIT and CMP instructions, in terms
1101 of clock cycles or words. */
1102 static const struct double_op_cost cycle_cost_double_op_mov
=
1110 /* Cycle count when memory is the destination operand is one larger than above
1111 for instructions that aren't MOV, BIT or CMP. */
1112 static const struct double_op_cost cycle_cost_double_op
=
1120 static const struct double_op_cost size_cost_double_op
=
1128 struct msp430_multlib_costs
1135 /* There is no precise size cost when using libcalls, instead it is disparaged
1136 relative to other instructions.
1137 The cycle costs are from the CALL to the RET, inclusive.
1138 FIXME muldi cost is not accurate. */
1139 static const struct msp430_multlib_costs cycle_cost_multlib_32bit
=
1144 /* 32bit multiply takes a few more instructions on 16bit hwmult. */
1145 static const struct msp430_multlib_costs cycle_cost_multlib_16bit
=
1150 /* TARGET_REGISTER_MOVE_COST
1151 There is only one class of general-purpose, non-fixed registers, and the
1152 relative cost of moving data between them is always the same.
1153 Therefore, the default of 2 is optimal. */
1155 #undef TARGET_MEMORY_MOVE_COST
1156 #define TARGET_MEMORY_MOVE_COST msp430_memory_move_cost
1158 /* Return the cost of moving data between registers and memory.
1159 The returned cost must be relative to the default TARGET_REGISTER_MOVE_COST
1161 IN is false if the value is to be written to memory. */
1163 msp430_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
1164 reg_class_t rclass ATTRIBUTE_UNUSED
,
1168 const struct double_op_cost
*cost_p
;
1169 /* Optimize with a code size focus by default, unless -O2 or above is
1171 bool speed
= (!optimize_size
&& optimize
>= 2);
1173 cost_p
= (speed
? &cycle_cost_double_op_mov
: &size_cost_double_op
);
1176 /* Reading from memory using indirect addressing is assumed to be the more
1178 cost
= cost_p
->ind2r
;
1182 /* All register to register moves cost 1 cycle or 1 word, so multiply by 2
1183 to get the costs relative to TARGET_REGISTER_MOVE_COST of 2. */
1187 /* For X, which must be a MEM RTX, return TRUE if it is an indirect memory
1188 reference, @Rn or @Rn+. */
1190 msp430_is_mem_indirect (rtx x
)
1192 gcc_assert (GET_CODE (x
) == MEM
);
1193 rtx op0
= XEXP (x
, 0);
1194 return (GET_CODE (op0
) == REG
|| GET_CODE (op0
) == POST_INC
);
1197 /* Costs of MSP430 instructions are generally based on the addressing mode
1198 combination of the source and destination operands.
1199 Given source operand SRC (which may be NULL to indicate a single-operand
1200 instruction) and destination operand DST return the cost of this
1203 msp430_costs (rtx src
, rtx dst
, bool speed
, rtx outer_rtx
)
1205 enum rtx_code src_code
= GET_CODE (src
);
1206 enum rtx_code dst_code
= GET_CODE (dst
);
1207 enum rtx_code outer_code
= GET_CODE (outer_rtx
);
1208 machine_mode outer_mode
= GET_MODE (outer_rtx
);
1209 const struct double_op_cost
*cost_p
;
1210 cost_p
= (speed
? &cycle_cost_double_op
: &size_cost_double_op
);
1212 if (outer_code
== TRUNCATE
1213 && (outer_mode
== QImode
1214 || outer_mode
== HImode
1215 || outer_mode
== PSImode
))
1216 /* Truncation to these modes is normally free as a side effect of the
1217 instructions themselves. */
1220 if (dst_code
== SYMBOL_REF
1221 || dst_code
== LABEL_REF
1222 || dst_code
== CONST_INT
)
1223 /* Catch RTX like (minus (const_int 0) (reg)) but don't add any cost. */
1229 return (dst_code
== REG
? cost_p
->r2r
1230 : (dst_code
== PC
? cost_p
->r2pc
: cost_p
->r2m
));
1236 return (dst_code
== REG
? cost_p
->imm2r
1237 : (dst_code
== PC
? cost_p
->imm2pc
: cost_p
->imm2m
));
1241 if (msp430_is_mem_indirect (src
))
1242 return (dst_code
== REG
? cost_p
->ind2r
: (dst_code
== PC
1246 return (dst_code
== REG
? cost_p
->mem2r
: (dst_code
== PC
1250 return cost_p
->mem2m
;
1254 /* Given source operand SRC and destination operand DST from the shift or
1255 rotate RTX OUTER_RTX, return the cost of performing that shift, assuming
1256 optimization for speed when SPEED is true. */
1258 msp430_shift_costs (rtx src
, rtx dst
, bool speed
, rtx outer_rtx
)
1261 enum rtx_code src_code
= GET_CODE (src
);
1262 enum rtx_code dst_code
= GET_CODE (dst
);
1263 const struct single_op_cost
*cost_p
;
1265 cost_p
= (speed
? &cycle_cost_single_op
: &size_cost_single_op
);
1267 if (src_code
!= CONST_INT
)
1268 /* The size or speed cost when the shift amount is unknown cannot be
1269 accurately calculated, so just disparage it slightly. */
1270 return 2 * msp430_costs (src
, dst
, speed
, outer_rtx
);
1272 if (use_helper_for_const_shift (GET_MODE (outer_rtx
), amt
= INTVAL (src
)))
1274 /* GCC sometimes tries to perform shifts in some very inventive ways,
1275 resulting in much larger code size usage than necessary, if
1276 they are disparaged too much here. So in general, if
1277 use_helper_for_const_shift thinks a helper should be used, obey
1278 that and don't disparage the shift any more than a regular
1279 instruction, even though the shift may actually cost more.
1280 This ensures that the RTL generated at the initial expand pass has the
1281 expected shift instructions, which can be mapped to the helper
1283 return msp430_costs (src
, dst
, speed
, outer_rtx
);
1288 /* Each shift by one place will be emitted individually. */
1293 return amt
* cost_p
->reg
;
1295 if (msp430_is_mem_indirect (dst
))
1296 return amt
* cost_p
->ind
;
1298 return amt
* cost_p
->mem
;
1300 return amt
* cost_p
->mem
;
1304 /* RRAM, RRCM, RRUM, RLAM are used for shift counts <= 4, otherwise, the 'X'
1306 Instructions which shift a MEM operand will never actually be output. It
1307 will always be copied into a register to allow for efficient shifting. So
1308 the cost just takes into account the cost of an additional copy in that
1310 return (amt
<= 4 ? (speed
? amt
: 1) : (speed
? amt
+ 1 : 2)
1311 + (dst_code
== REG
? 0
1312 : msp430_costs (dst
, gen_rtx_REG (HImode
, 10), speed
, outer_rtx
)));
1315 /* Given source operand SRC and destination operand DST from the MULT/DIV/MOD
1316 RTX OUTER_RTX, return the cost of performing that operation, assuming
1317 optimization for speed when SPEED is true. */
1319 msp430_muldiv_costs (rtx src
, rtx dst
, bool speed
, rtx outer_rtx
,
1320 machine_mode outer_mode
)
1322 enum rtx_code outer_code
= GET_CODE (outer_rtx
);
1323 const struct msp430_multlib_costs
*cost_p
;
1324 cost_p
= (msp430_use_16bit_hwmult ()
1325 ? &cycle_cost_multlib_32bit
1326 : &cycle_cost_multlib_16bit
);
1329 /* Only used in some calculations. */
1330 int mode_factor
= 1;
1331 if (outer_mode
== SImode
)
1333 else if (outer_mode
== PSImode
)
1334 /* PSImode multiplication is performed using SImode operands, so has extra
1335 cost to factor in the conversions necessary before/after the
1338 else if (outer_mode
== DImode
)
1343 /* The codesize cost of using a helper function to perform the
1344 multiplication or division cannot be accurately calculated, since the
1345 cost depends on how many times the operation is performed in the
1347 if (outer_code
!= MULT
)
1348 /* Division is always expensive. */
1350 else if (((msp430_use_16bit_hwmult () && outer_mode
!= DImode
)
1351 || msp430_use_32bit_hwmult ()
1352 || msp430_use_f5_series_hwmult ()))
1353 /* When the hardware multiplier is available, only disparage
1358 return factor
* mode_factor
* msp430_costs (src
, dst
, speed
, outer_rtx
);
1361 /* When there is hardware multiply support, there is a relatively low, fixed
1362 cycle cost to performing any multiplication, but when there is no hardware
1363 multiply support it is very costly. That precise cycle cost has not been
1365 Division is extra slow since it always uses a software library.
1366 The 16-bit hardware multiply library cannot be used to produce 64-bit
1368 if (outer_code
!= MULT
|| !msp430_has_hwmult ()
1369 || (outer_mode
== DImode
&& msp430_use_16bit_hwmult ()))
1371 factor
= (outer_code
== MULT
? 50 : 70);
1372 return factor
* mode_factor
* msp430_costs (src
, dst
, speed
, outer_rtx
);
1379 /* Include the cost of copying the operands into and out of the hardware
1380 multiply routine. */
1381 return cost_p
->mulhi
+ (3 * msp430_costs (src
, dst
, speed
, outer_rtx
));
1384 /* Extra factor for the conversions necessary to do PSI->SI before the
1389 return factor
* (cost_p
->mulsi
1390 + (6 * msp430_costs (src
, dst
, speed
, outer_rtx
)));
1394 return cost_p
->muldi
+ (12 * msp430_costs (src
, dst
, speed
, outer_rtx
));
1398 /* Recurse within X to find the actual destination operand of the expression.
1400 (plus (ashift (minus (ashift (reg)
1402 should return the reg RTX. */
1404 msp430_get_inner_dest_code (rtx x
)
1406 enum rtx_code code
= GET_CODE (x
);
1407 rtx op0
= XEXP (x
, 0);
1418 /* Return the MEM expr not the inner REG for these cases. */
1419 switch (GET_CODE (op0
))
1429 /* return MEM (PLUS (REG) (CONST)) */
1430 if (GET_CODE (XEXP (op0
, 0)) == REG
)
1432 if (GET_CODE (XEXP (op0
, 1)) == CONST_INT
1433 || GET_CODE (XEXP (op0
, 1)) == CONST
1434 || GET_CODE (XEXP (op0
, 1)) == LABEL_REF
1435 || GET_CODE (XEXP (op0
, 1)) == SYMBOL_REF
)
1438 return msp430_get_inner_dest_code (op0
);
1440 return msp430_get_inner_dest_code (op0
);
1443 if (GET_RTX_FORMAT (code
)[0] != 'e')
1445 return msp430_get_inner_dest_code (op0
);
1450 if (op0
== NULL_RTX
)
1454 if (GET_RTX_FORMAT (code
)[0] != 'e'
1455 && code
!= ENTRY_VALUE
)
1457 return msp430_get_inner_dest_code (op0
);
1462 /* Calculate the cost of an MSP430 single-operand instruction, for operand DST
1463 within the RTX OUTER_RTX, optimizing for speed if SPEED is true. */
1465 msp430_single_op_cost (rtx dst
, bool speed
, rtx
/* outer_rtx */)
1467 enum rtx_code dst_code
= GET_CODE (dst
);
1468 const struct single_op_cost
*cost_p
;
1469 const struct double_op_cost
*double_op_cost_p
;
1471 cost_p
= (speed
? &cycle_cost_single_op
: &size_cost_single_op
);
1472 double_op_cost_p
= (speed
? &cycle_cost_double_op
: &size_cost_double_op
);
1479 if (msp430_is_mem_indirect (dst
))
1489 /* A constant value would need to be copied into a register first. */
1490 return double_op_cost_p
->imm2r
+ cost_p
->reg
;
1497 #undef TARGET_RTX_COSTS
1498 #define TARGET_RTX_COSTS msp430_rtx_costs
1500 /* This target hook describes the relative costs of RTL expressions.
1501 The function recurses to just before the lowest level of the expression,
1502 when both of the operands of the expression can be examined at the same time.
1503 This is because the cost of the expression depends on the specific
1504 addressing mode combination of the operands.
1505 The hook returns true when all subexpressions of X have been processed, and
1506 false when rtx_cost should recurse. */
1508 msp430_rtx_costs (rtx x
,
1510 int outer_code ATTRIBUTE_UNUSED
,
1511 int opno ATTRIBUTE_UNUSED
,
1515 enum rtx_code code
= GET_CODE (x
);
1517 rtx dst_inner
, src_inner
;
1521 if (GET_RTX_LENGTH (code
) == 1)
1522 /* Some RTX that are single-op in GCC are double-op when translated to
1523 MSP430 instructions e.g NOT, NEG, ZERO_EXTEND. */
1532 /* Ignoring SET improves codesize. */
1537 if (outer_code
== MEM
)
1538 /* Do not add any cost for the plus itself, but recurse in case there
1539 are more complicated RTX inside. */
1553 dst_inner
= msp430_get_inner_dest_code (dst
);
1554 src_inner
= msp430_get_inner_dest_code (src
);
1555 *total
= COSTS_N_INSNS (msp430_costs (src_inner
, dst_inner
, speed
, x
));
1566 dst_inner
= msp430_get_inner_dest_code (dst
);
1567 src_inner
= msp430_get_inner_dest_code (src
);
1568 *total
= COSTS_N_INSNS (msp430_shift_costs (src_inner
, dst_inner
,
1581 dst_inner
= msp430_get_inner_dest_code (dst
);
1582 src_inner
= msp430_get_inner_dest_code (src
);
1583 *total
= COSTS_N_INSNS (msp430_muldiv_costs (src_inner
, dst_inner
, speed
,
1589 dst_inner
= msp430_get_inner_dest_code (dst
);
1590 *total
= COSTS_N_INSNS (msp430_single_op_cost (dst_inner
, speed
, x
));
1607 *total
= COSTS_N_INSNS (2);
1608 else if (mode
== DImode
)
1609 *total
= COSTS_N_INSNS (4);
1613 /* PSImode operands are expensive when in memory. */
1614 if (mode
== PSImode
)
1615 *total
= COSTS_N_INSNS (1);
1616 else if (mode
== SImode
)
1617 *total
= COSTS_N_INSNS (2);
1618 else if (mode
== DImode
)
1619 *total
= COSTS_N_INSNS (4);
1620 /* Recurse into the MEM. */
1633 /* Conditions are mostly equivalent, changing their relative
1634 costs has no effect. */
1643 /* Other unhandled expressions. */
1651 #undef TARGET_INSN_COST
1652 #define TARGET_INSN_COST msp430_insn_cost
1655 msp430_insn_cost (rtx_insn
*insn
, bool speed ATTRIBUTE_UNUSED
)
1657 if (recog_memoized (insn
) < 0)
1660 /* The returned cost must be relative to COSTS_N_INSNS (1). An insn with a
1661 length of 2 bytes is the smallest possible size and so must be equivalent
1662 to COSTS_N_INSNS (1). */
1663 return COSTS_N_INSNS (get_attr_length (insn
) / 2);
1665 /* FIXME Add more detailed costs when optimizing for speed.
1666 For now the length of the instruction is a good approximiation and roughly
1667 correlates with cycle cost. */
1671 /* Function Entry and Exit */
1673 /* The MSP430 call frame looks like this:
1676 +--------------------+
1680 +--------------------+ <-- "arg pointer"
1682 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1684 +--------------------+
1685 | SR if this func has|
1686 | been called via an |
1688 +--------------------+ <-- SP before prologue, also AP
1690 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1692 +--------------------+ <-- "frame pointer"
1696 +--------------------+
1700 +--------------------+ <-- SP during function
1705 /* We use this to wrap all emitted insns in the prologue, so they get
1706 the "frame-related" (/f) flag set. */
1710 RTX_FRAME_RELATED_P (x
) = 1;
1714 /* This is the one spot that decides if a register is to be saved and
1715 restored in the prologue/epilogue. */
1717 msp430_preserve_reg_p (int regno
)
1719 /* PC, SP, SR, and the constant generator. */
1723 /* FIXME: add interrupt, EH, etc. */
1724 if (crtl
->calls_eh_return
)
1727 /* Shouldn't be more than the above, but just in case... */
1728 if (fixed_regs
[regno
])
1731 /* For interrupt functions we must save and restore the used regs that
1732 would normally be caller-saved (R11->R15). */
1733 if (msp430_is_interrupt_func () && regno
>= 11 && regno
<= 15)
1735 if (crtl
->is_leaf
&& df_regs_ever_live_p (regno
))
1736 /* If the interrupt func is a leaf then we only need to restore the
1737 caller-saved regs that are used. */
1739 else if (!crtl
->is_leaf
)
1740 /* If the interrupt function is not a leaf we must save all
1741 caller-saved regs in case the callee modifies them. */
1745 if (!call_used_or_fixed_reg_p (regno
)
1746 && df_regs_ever_live_p (regno
))
1752 /* Compute all the frame-related fields in our machine_function
1755 msp430_compute_frame_info (void)
1759 cfun
->machine
->computed
= 1;
1760 cfun
->machine
->framesize_regs
= 0;
1761 cfun
->machine
->framesize_locals
= get_frame_size ();
1762 cfun
->machine
->framesize_outgoing
= crtl
->outgoing_args_size
;
1764 for (i
= 0; i
< ARG_POINTER_REGNUM
; i
++)
1765 if (msp430_preserve_reg_p (i
))
1767 cfun
->machine
->need_to_save
[i
] = 1;
1768 cfun
->machine
->framesize_regs
+= (TARGET_LARGE
? 4 : 2);
1771 cfun
->machine
->need_to_save
[i
] = 0;
1773 if ((cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
) & 1)
1774 cfun
->machine
->framesize_locals
++;
1776 cfun
->machine
->framesize
= (cfun
->machine
->framesize_regs
1777 + cfun
->machine
->framesize_locals
1778 + cfun
->machine
->framesize_outgoing
);
1781 /* Attribute Handling. */
1783 const char * const ATTR_INTR
= "interrupt";
1784 const char * const ATTR_WAKEUP
= "wakeup";
1785 const char * const ATTR_NAKED
= "naked";
1786 const char * const ATTR_REENT
= "reentrant";
1787 const char * const ATTR_CRIT
= "critical";
1788 const char * const ATTR_LOWER
= "lower";
1789 const char * const ATTR_UPPER
= "upper";
1790 const char * const ATTR_EITHER
= "either";
1791 const char * const ATTR_NOINIT
= "noinit";
1792 const char * const ATTR_PERSIST
= "persistent";
1795 has_attr (const char * attr
, tree decl
)
1797 if (decl
== NULL_TREE
)
1799 return lookup_attribute (attr
, DECL_ATTRIBUTES (decl
)) != NULL_TREE
;
1803 is_interrupt_func (tree decl
= current_function_decl
)
1805 return has_attr (ATTR_INTR
, decl
);
1808 /* Returns true if the current function has the "interrupt" attribute. */
1811 msp430_is_interrupt_func (void)
1813 return is_interrupt_func (current_function_decl
);
1817 is_wakeup_func (tree decl
= current_function_decl
)
1819 return is_interrupt_func (decl
) && has_attr (ATTR_WAKEUP
, decl
);
1823 is_naked_func (tree decl
= current_function_decl
)
1825 return has_attr (ATTR_NAKED
, decl
);
1829 is_reentrant_func (tree decl
= current_function_decl
)
1831 return has_attr (ATTR_REENT
, decl
);
1835 is_critical_func (tree decl
= current_function_decl
)
1837 return has_attr (ATTR_CRIT
, decl
);
1841 has_section_name (const char * name
, tree decl
= current_function_decl
)
1843 if (decl
== NULL_TREE
)
1845 return (DECL_SECTION_NAME (decl
)
1846 && (strcmp (name
, DECL_SECTION_NAME (decl
)) == 0));
1849 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1850 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
1851 msp430_allocate_stack_slots_for_args
1854 msp430_allocate_stack_slots_for_args (void)
1856 /* Naked functions should not allocate stack slots for arguments. */
1857 return ! is_naked_func ();
1860 #undef TARGET_WARN_FUNC_RETURN
1861 #define TARGET_WARN_FUNC_RETURN msp430_warn_func_return
1864 msp430_warn_func_return (tree decl
)
1866 /* Naked functions are implemented entirely in assembly, including the
1867 return sequence, so suppress warnings about this. */
1868 return !is_naked_func (decl
);
1871 /* Verify MSP430 specific attributes. */
1872 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1875 msp430_attr (tree
* node
,
1878 int flags ATTRIBUTE_UNUSED
,
1879 bool * no_add_attrs
)
1881 gcc_assert (DECL_P (* node
));
1883 /* Only the interrupt attribute takes an argument. */
1886 tree value
= TREE_VALUE (args
);
1888 switch (TREE_CODE (value
))
1891 if ( strcmp (TREE_STRING_POINTER (value
), "reset")
1892 && strcmp (TREE_STRING_POINTER (value
), "nmi")
1893 && strcmp (TREE_STRING_POINTER (value
), "watchdog"))
1894 /* Allow the attribute to be added - the linker script
1895 being used may still recognise this name. */
1896 warning (OPT_Wattributes
,
1897 "unrecognized interrupt vector argument of %qE attribute",
1902 if (wi::gtu_p (wi::to_wide (value
), 63))
1903 /* Allow the attribute to be added - the linker script
1904 being used may still recognise this value. */
1905 warning (OPT_Wattributes
,
1906 "numeric argument of %qE attribute must be in range [0-63]",
1911 warning (OPT_Wattributes
,
1912 "argument of %qE attribute is not a string constant "
1914 *no_add_attrs
= true;
1919 const char * message
= NULL
;
1921 if (TREE_CODE (* node
) != FUNCTION_DECL
)
1923 message
= "%qE attribute only applies to functions";
1925 else if (TREE_NAME_EQ (name
, ATTR_INTR
))
1927 if (TREE_CODE (TREE_TYPE (* node
)) == FUNCTION_TYPE
1928 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node
))))
1929 message
= "interrupt handlers must be void";
1932 /* Ensure interrupt handlers never get optimised out. */
1933 TREE_USED (* node
) = 1;
1934 DECL_PRESERVE_P (* node
) = 1;
1936 if (is_critical_func (* node
))
1938 /* We always ignore the critical attribute when interrupt and
1939 critical are used together. */
1940 warning (OPT_Wattributes
,
1941 "critical attribute has no effect on interrupt functions");
1942 DECL_ATTRIBUTES (*node
) = remove_attribute (ATTR_CRIT
,
1943 DECL_ATTRIBUTES (* node
));
1946 else if (TREE_NAME_EQ (name
, ATTR_CRIT
))
1948 if (is_interrupt_func ( *node
))
1949 message
= "critical attribute has no effect on interrupt functions";
1954 warning (OPT_Wattributes
, message
, name
);
1955 * no_add_attrs
= true;
1962 msp430_section_attr (tree
* node
,
1965 int flags ATTRIBUTE_UNUSED
,
1966 bool * no_add_attrs ATTRIBUTE_UNUSED
)
1968 gcc_assert (DECL_P (* node
));
1969 gcc_assert (args
== NULL
);
1971 const char * message
= NULL
;
1973 /* The "noinit", "persistent", and "section" attributes are handled
1974 generically, so we cannot set up additional target-specific attribute
1975 exclusions using the existing mechanism. */
1976 if (has_attr (ATTR_NOINIT
, *node
) && !TREE_NAME_EQ (name
, "lower"))
1977 message
= G_("ignoring attribute %qE because it conflicts with "
1978 "attribute %<noinit%>");
1979 else if (has_attr ("section", *node
) && !TREE_NAME_EQ (name
, "lower"))
1980 message
= G_("ignoring attribute %qE because it conflicts with "
1981 "attribute %<section%>");
1982 else if (has_attr (ATTR_PERSIST
, *node
) && !TREE_NAME_EQ (name
, "lower"))
1983 message
= G_("ignoring attribute %qE because it conflicts with "
1984 "attribute %<persistent%>");
1985 /* It does not make sense to use upper/lower/either attributes without
1987 Without -mlarge, "lower" is the default and only region, so is redundant.
1988 Without -mlarge, "upper" will (and "either" might) place code/data in the
1989 upper region, which for data could result in relocation overflows, and for
1990 code could result in stack mismanagement and incorrect call/return
1992 else if (!TARGET_LARGE
)
1993 message
= G_("%qE attribute ignored. Large memory model (%<-mlarge%>) "
1998 warning (OPT_Wattributes
, message
, name
);
1999 * no_add_attrs
= true;
2005 /* Helper to define attribute exclusions. */
2006 #define ATTR_EXCL(name, function, type, variable) \
2007 { name, function, type, variable }
2009 /* "reentrant", "critical" and "naked" functions must conflict because
2010 they all modify the prologue or epilogue of functions in mutually exclusive
2012 static const struct attribute_spec::exclusions attr_reent_exclusions
[] =
2014 ATTR_EXCL (ATTR_NAKED
, true, true, true),
2015 ATTR_EXCL (ATTR_CRIT
, true, true, true),
2016 ATTR_EXCL (NULL
, false, false, false)
2019 static const struct attribute_spec::exclusions attr_naked_exclusions
[] =
2021 ATTR_EXCL (ATTR_REENT
, true, true, true),
2022 ATTR_EXCL (ATTR_CRIT
, true, true, true),
2023 ATTR_EXCL (NULL
, false, false, false)
2026 static const struct attribute_spec::exclusions attr_crit_exclusions
[] =
2028 ATTR_EXCL (ATTR_REENT
, true, true, true),
2029 ATTR_EXCL (ATTR_NAKED
, true, true, true),
2030 ATTR_EXCL (NULL
, false, false, false)
2033 /* Attributes which put the given object in a specific section must conflict
2034 with one another. */
2035 static const struct attribute_spec::exclusions attr_lower_exclusions
[] =
2037 ATTR_EXCL (ATTR_UPPER
, true, true, true),
2038 ATTR_EXCL (ATTR_EITHER
, true, true, true),
2039 ATTR_EXCL (NULL
, false, false, false)
2042 static const struct attribute_spec::exclusions attr_upper_exclusions
[] =
2044 ATTR_EXCL (ATTR_LOWER
, true, true, true),
2045 ATTR_EXCL (ATTR_EITHER
, true, true, true),
2046 ATTR_EXCL (NULL
, false, false, false)
2049 static const struct attribute_spec::exclusions attr_either_exclusions
[] =
2051 ATTR_EXCL (ATTR_LOWER
, true, true, true),
2052 ATTR_EXCL (ATTR_UPPER
, true, true, true),
2053 ATTR_EXCL (NULL
, false, false, false)
2056 #undef TARGET_ATTRIBUTE_TABLE
2057 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
2059 /* Table of MSP430-specific attributes. */
2060 TARGET_GNU_ATTRIBUTES (msp430_attribute_table
,
2062 /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
2063 affects_type_identity, handler, exclude } */
2064 { ATTR_INTR
, 0, 1, true, false, false, false, msp430_attr
, NULL
},
2065 { ATTR_NAKED
, 0, 0, true, false, false, false, msp430_attr
,
2066 attr_naked_exclusions
},
2067 { ATTR_REENT
, 0, 0, true, false, false, false, msp430_attr
,
2068 attr_reent_exclusions
},
2069 { ATTR_CRIT
, 0, 0, true, false, false, false, msp430_attr
,
2070 attr_crit_exclusions
},
2071 { ATTR_WAKEUP
, 0, 0, true, false, false, false, msp430_attr
, NULL
},
2073 { ATTR_LOWER
, 0, 0, true, false, false, false, msp430_section_attr
,
2074 attr_lower_exclusions
},
2075 { ATTR_UPPER
, 0, 0, true, false, false, false, msp430_section_attr
,
2076 attr_upper_exclusions
},
2077 { ATTR_EITHER
, 0, 0, true, false, false, false, msp430_section_attr
,
2078 attr_either_exclusions
}
2081 #undef TARGET_HANDLE_GENERIC_ATTRIBUTE
2082 #define TARGET_HANDLE_GENERIC_ATTRIBUTE msp430_handle_generic_attribute
2085 msp430_handle_generic_attribute (tree
*node
,
2087 tree args ATTRIBUTE_UNUSED
,
2088 int flags ATTRIBUTE_UNUSED
,
2092 const char *message
= NULL
;
2094 /* Permit the "lower" attribute to be set on variables with the "section",
2095 "noinit" and "persistent" attributes. This is used to indicate that the
2096 corresponding output section will be in lower memory, so a 430X
2097 instruction is not required to handle it. */
2098 if (has_attr (ATTR_LOWER
, *node
)
2099 && !(TREE_NAME_EQ (name
, "section") || TREE_NAME_EQ (name
, ATTR_PERSIST
)
2100 || TREE_NAME_EQ (name
, ATTR_NOINIT
)))
2101 message
= G_("ignoring attribute %qE because it conflicts with "
2102 "attribute %<lower%>");
2103 else if (has_attr (ATTR_UPPER
, *node
))
2104 message
= G_("ignoring attribute %qE because it conflicts with "
2105 "attribute %<upper%>");
2106 else if (has_attr (ATTR_EITHER
, *node
))
2107 message
= G_("ignoring attribute %qE because it conflicts with "
2108 "attribute %<either%>");
2112 warning (OPT_Wattributes
, message
, name
);
2113 *no_add_attrs
= true;
2119 /* Given a non-automatic VAR_DECL which can possibly have a section, return
2120 true if the variable will definitely be placed in the lower memory
2121 region (below address 0x10000). */
2123 msp430_var_in_low_mem (tree decl
)
2125 gcc_assert (VAR_P (decl
));
2127 /* "noinit" variables are always placed in the lower memory region. */
2128 if (has_attr (ATTR_UPPER
, decl
)
2129 || has_attr (ATTR_EITHER
, decl
)
2130 || has_attr (ATTR_PERSIST
, decl
)
2131 /* Unless the variable is marked with the lower or noinit attribute, we
2132 cannot assume that it is in the lower region if it is marked with the
2133 section attribute or -mdata-region={upper,either,none} have been
2135 The noinit and section attributes conflict. */
2136 || (!has_attr (ATTR_LOWER
, decl
) && !has_attr (ATTR_NOINIT
, decl
)
2137 && (has_attr ("section", decl
)
2138 || msp430_data_region
== MSP430_REGION_UPPER
2139 || msp430_data_region
== MSP430_REGION_EITHER
2140 || msp430_data_region
== MSP430_REGION_ANY
)))
2145 #undef TARGET_ENCODE_SECTION_INFO
2146 #define TARGET_ENCODE_SECTION_INFO msp430_encode_section_info
2148 /* Encode whether a SYMBOL_REF is definitely in the lower memory region. */
2150 msp430_encode_section_info (tree decl
, rtx rtl
, int first
)
2153 default_encode_section_info (decl
, rtl
, first
);
2155 /* Careful not to prod global register variables. */
2158 symbol
= XEXP (rtl
, 0);
2159 if (GET_CODE (symbol
) != SYMBOL_REF
)
2163 && (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
2164 && msp430_var_in_low_mem (decl
))
2165 SYMBOL_REF_FLAGS (symbol
) = SYMBOL_FLAG_LOW_MEM
;
2168 #undef TARGET_ASM_FUNCTION_PROLOGUE
2169 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
2172 msp430_start_function (FILE *outfile
)
2176 fprintf (outfile
, "; start of function\n");
2178 if (DECL_ATTRIBUTES (current_function_decl
) != NULL_TREE
)
2180 fprintf (outfile
, "; attributes: ");
2181 if (is_naked_func ())
2182 fprintf (outfile
, "naked ");
2183 if (msp430_is_interrupt_func ())
2184 fprintf (outfile
, "interrupt ");
2185 if (is_reentrant_func ())
2186 fprintf (outfile
, "reentrant ");
2187 if (is_critical_func ())
2188 fprintf (outfile
, "critical ");
2189 if (is_wakeup_func ())
2190 fprintf (outfile
, "wakeup ");
2191 fprintf (outfile
, "\n");
2194 fprintf (outfile
, "; framesize_regs: %d\n",
2195 cfun
->machine
->framesize_regs
);
2196 fprintf (outfile
, "; framesize_locals: %d\n",
2197 cfun
->machine
->framesize_locals
);
2198 fprintf (outfile
, "; framesize_outgoing: %d\n",
2199 cfun
->machine
->framesize_outgoing
);
2200 fprintf (outfile
, "; framesize: %d\n", cfun
->machine
->framesize
);
2201 fprintf (outfile
, "; elim ap -> fp %d\n",
2202 msp430_initial_elimination_offset (ARG_POINTER_REGNUM
,
2203 FRAME_POINTER_REGNUM
));
2204 fprintf (outfile
, "; elim fp -> sp %d\n",
2205 msp430_initial_elimination_offset (FRAME_POINTER_REGNUM
,
2206 STACK_POINTER_REGNUM
));
2209 fprintf (outfile
, "; saved regs:");
2210 for (r
= 0; r
< ARG_POINTER_REGNUM
; r
++)
2211 if (cfun
->machine
->need_to_save
[r
])
2213 fprintf (outfile
, " %s", reg_names
[r
]);
2217 fprintf (outfile
, "(none)");
2218 fprintf (outfile
, "\n");
2221 /* Common code to change the stack pointer. */
2223 increment_stack (HOST_WIDE_INT amount
)
2226 rtx sp
= stack_pointer_rtx
;
2233 inc
= GEN_INT (- amount
);
2235 F (emit_insn (gen_subpsi3 (sp
, sp
, inc
)));
2237 F (emit_insn (gen_subhi3 (sp
, sp
, inc
)));
2241 inc
= GEN_INT (amount
);
2243 F (emit_insn (gen_addpsi3 (sp
, sp
, inc
)));
2245 F (emit_insn (gen_addhi3 (sp
, sp
, inc
)));
2250 msp430_start_function (FILE *file
, const char *name
, tree decl
)
2254 int_attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2255 if (int_attr
!= NULL_TREE
)
2257 tree intr_vector
= TREE_VALUE (int_attr
);
2259 if (intr_vector
!= NULL_TREE
)
2263 /* Interrupt vector sections should be unique, but use of weak
2264 functions implies multiple definitions. */
2265 if (DECL_WEAK (decl
))
2267 error ("argument to interrupt attribute is unsupported for weak "
2271 intr_vector
= TREE_VALUE (intr_vector
);
2273 /* The interrupt attribute has a vector value. Turn this into a
2274 section name, switch to that section and put the address of
2275 the current function into that vector slot. Note msp430_attr()
2276 has already verified the vector name for us. */
2277 if (TREE_CODE (intr_vector
) == STRING_CST
)
2278 sprintf (buf
, "__interrupt_vector_%.80s",
2279 TREE_STRING_POINTER (intr_vector
));
2280 else /* TREE_CODE (intr_vector) == INTEGER_CST */
2281 sprintf (buf
, "__interrupt_vector_%u",
2282 (unsigned int) TREE_INT_CST_LOW (intr_vector
));
2284 switch_to_section (get_section (buf
, SECTION_CODE
, decl
));
2285 fputs ("\t.word\t", file
);
2286 assemble_name (file
, name
);
2292 switch_to_section (function_section (decl
));
2293 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
2294 ASM_OUTPUT_FUNCTION_LABEL (file
, name
, decl
);
2297 static const char * const lower_prefix
= ".lower";
2298 static const char * const upper_prefix
= ".upper";
2299 static const char * const either_prefix
= ".either";
2301 /* Generate a prefix for a section name, based upon
2302 the region into which the object should be placed. */
2305 gen_prefix (tree decl
)
2307 if (DECL_ONE_ONLY (decl
))
2310 /* If the user has specified a particular section then do not use any
2312 if (has_attr ("section", decl
))
2315 /* If the function has been put in the .lowtext section (because it is an
2316 interrupt handler, and the large memory model is used), then do not add
2318 if (has_section_name (".lowtext", decl
))
2321 /* Memory regions require the large memory model. */
2325 /* Note that we always apply the lower prefix when the attribute has been
2326 used. But we only apply the lower prefix when the lower region has been
2327 specified by a command line option if -muse-lower-region-prefix has also
2329 if (has_attr (ATTR_LOWER
, decl
))
2330 return lower_prefix
;
2332 if (has_attr (ATTR_UPPER
, decl
))
2333 return upper_prefix
;
2335 if (has_attr (ATTR_EITHER
, decl
))
2336 return either_prefix
;
2338 if (TREE_CODE (decl
) == FUNCTION_DECL
)
2340 if ((msp430_code_region
== MSP430_REGION_LOWER
)
2341 && TARGET_USE_LOWER_REGION_PREFIX
)
2342 return lower_prefix
;
2344 if (msp430_code_region
== MSP430_REGION_UPPER
)
2345 return upper_prefix
;
2347 if (msp430_code_region
== MSP430_REGION_EITHER
)
2348 return either_prefix
;
2352 if ((msp430_data_region
== MSP430_REGION_LOWER
)
2353 && TARGET_USE_LOWER_REGION_PREFIX
)
2354 return lower_prefix
;
2356 if (msp430_data_region
== MSP430_REGION_UPPER
)
2357 return upper_prefix
;
2359 if (msp430_data_region
== MSP430_REGION_EITHER
)
2360 return either_prefix
;
2366 #undef TARGET_ASM_SELECT_SECTION
2367 #define TARGET_ASM_SELECT_SECTION msp430_select_section
2370 msp430_select_section (tree decl
, int reloc
, unsigned HOST_WIDE_INT align
)
2373 const char *sec_name
;
2374 const char *base_sec_name
;
2376 gcc_assert (decl
!= NULL_TREE
);
2378 if (TREE_CODE (decl
) == STRING_CST
2379 || TREE_CODE (decl
) == CONSTRUCTOR
2380 || TREE_CODE (decl
) == INTEGER_CST
2381 || TREE_CODE (decl
) == VECTOR_CST
2382 || TREE_CODE (decl
) == COMPLEX_CST
)
2383 return default_select_section (decl
, reloc
, align
);
2385 /* In large mode we must make sure that interrupt handlers are put into
2386 low memory as the vector table only accepts 16-bit addresses. */
2387 if (TARGET_LARGE
&& TREE_CODE (decl
) == FUNCTION_DECL
2388 && is_interrupt_func (decl
))
2389 return get_section (".lowtext", SECTION_CODE
| SECTION_WRITE
, decl
);
2391 /* The "noinit" and "persistent" attributes are handled generically. */
2392 if (has_attr (ATTR_NOINIT
, decl
) || has_attr (ATTR_PERSIST
, decl
))
2393 return default_elf_select_section (decl
, reloc
, align
);
2395 prefix
= gen_prefix (decl
);
2397 switch (categorize_decl_for_section (decl
, reloc
))
2401 return text_section
;
2402 base_sec_name
= ".text";
2406 return data_section
;
2407 base_sec_name
= ".data";
2412 base_sec_name
= ".bss";
2416 return readonly_data_section
;
2417 base_sec_name
= ".rodata";
2420 /* Enable merging of constant data by the GNU linker using
2421 default_elf_select_section and therefore enabling creation of
2422 sections with the SHF_MERGE flag. */
2423 case SECCAT_RODATA_MERGE_STR
:
2424 case SECCAT_RODATA_MERGE_STR_INIT
:
2425 case SECCAT_RODATA_MERGE_CONST
:
2426 return default_elf_select_section (decl
, reloc
, align
);
2428 /* The sections listed below are not supported for MSP430.
2429 They should not be generated, but in case they are, we use
2430 default_select_section so they get placed in sections
2431 the msp430 assembler and linker understand. */
2432 /* "small data" sections are not supported. */
2433 case SECCAT_SRODATA
:
2436 /* Thread-local storage (TLS) is not supported. */
2439 /* Sections used by a dynamic linker are not supported. */
2440 case SECCAT_DATA_REL
:
2441 case SECCAT_DATA_REL_LOCAL
:
2442 case SECCAT_DATA_REL_RO
:
2443 case SECCAT_DATA_REL_RO_LOCAL
:
2444 return default_select_section (decl
, reloc
, align
);
2450 sec_name
= ACONCAT ((prefix
, base_sec_name
, DECL_SECTION_NAME (decl
), NULL
));
2452 return get_named_section (decl
, sec_name
, 0);
2455 #undef TARGET_ASM_FUNCTION_SECTION
2456 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
2459 msp430_function_section (tree decl
, enum node_frequency freq
, bool startup
,
2464 gcc_assert (DECL_SECTION_NAME (decl
) != NULL
);
2465 name
= DECL_SECTION_NAME (decl
);
2467 const char * prefix
= gen_prefix (decl
);
2469 || startswith (name
, prefix
))
2470 return default_function_section (decl
, freq
, startup
, exit
);
2472 name
= ACONCAT ((prefix
, name
, NULL
));
2473 return get_named_section (decl
, name
, 0);
2476 #undef TARGET_SECTION_TYPE_FLAGS
2477 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
2480 msp430_section_type_flags (tree decl
, const char * name
, int reloc
)
2482 if (startswith (name
, lower_prefix
))
2483 name
+= strlen (lower_prefix
);
2484 else if (startswith (name
, upper_prefix
))
2485 name
+= strlen (upper_prefix
);
2486 else if (startswith (name
, either_prefix
))
2487 name
+= strlen (either_prefix
);
2489 return default_section_type_flags (decl
, name
, reloc
);
2492 #undef TARGET_ASM_UNIQUE_SECTION
2493 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
2496 msp430_unique_section (tree decl
, int reloc
)
2498 gcc_assert (decl
!= NULL_TREE
);
2500 /* In large mode we must make sure that interrupt handlers are put into
2501 low memory as the vector table only accepts 16-bit addresses. */
2502 if (TARGET_LARGE
&& TREE_CODE (decl
) == FUNCTION_DECL
2503 && is_interrupt_func (decl
))
2505 set_decl_section_name (decl
, ".lowtext");
2509 default_unique_section (decl
, reloc
);
2511 const char * prefix
;
2513 if ( TREE_CODE (decl
) == STRING_CST
2514 || TREE_CODE (decl
) == CONSTRUCTOR
2515 || TREE_CODE (decl
) == INTEGER_CST
2516 || TREE_CODE (decl
) == VECTOR_CST
2517 || TREE_CODE (decl
) == COMPLEX_CST
2518 || (prefix
= gen_prefix (decl
)) == NULL
)
2521 const char * dec_name
= DECL_SECTION_NAME (decl
);
2522 char * name
= ACONCAT ((prefix
, dec_name
, NULL
));
2524 set_decl_section_name (decl
, name
);
2527 /* Emit a declaration of a common symbol.
2528 If a data region is in use then put the symbol into the
2529 equivalent .bss section instead.
2530 If LOCAL is 1, then DECL is for a local common variable. */
2532 msp430_output_aligned_decl_common (FILE * stream
,
2535 unsigned HOST_WIDE_INT size
,
2539 /* Only emit a common symbol if the variable does not have a specific section
2541 if ((msp430_data_region
== MSP430_REGION_ANY
2542 || ((msp430_data_region
== MSP430_REGION_LOWER
)
2543 && !TARGET_USE_LOWER_REGION_PREFIX
))
2544 && !(decl
!= NULL_TREE
&& DECL_SECTION_NAME (decl
))
2545 && !has_attr (ATTR_EITHER
, decl
)
2546 && !has_attr (ATTR_LOWER
, decl
)
2547 && !has_attr (ATTR_UPPER
, decl
)
2548 && !has_attr (ATTR_PERSIST
, decl
)
2549 && !has_attr (ATTR_NOINIT
, decl
))
2553 fprintf (stream
, LOCAL_ASM_OP
);
2554 assemble_name (stream
, name
);
2555 fprintf (stream
, "\n");
2557 fprintf (stream
, COMMON_ASM_OP
);
2558 assemble_name (stream
, name
);
2559 fprintf (stream
, "," HOST_WIDE_INT_PRINT_UNSIGNED
",%u\n",
2560 size
, align
/ BITS_PER_UNIT
);
2567 sec
= msp430_select_section (decl
, 0, align
);
2569 switch (msp430_data_region
)
2571 case MSP430_REGION_UPPER
:
2572 sec
= get_named_section (NULL
, ".upper.bss", 0);
2574 case MSP430_REGION_LOWER
:
2575 sec
= get_named_section (NULL
, ".lower.bss", 0);
2577 case MSP430_REGION_EITHER
:
2578 sec
= get_named_section (NULL
, ".either.bss", 0);
2583 gcc_assert (sec
!= NULL
);
2585 switch_to_section (sec
);
2586 ASM_OUTPUT_ALIGN (stream
, floor_log2 (align
/ BITS_PER_UNIT
));
2589 targetm
.asm_out
.globalize_label (stream
, name
);
2590 ASM_WEAKEN_LABEL (stream
, name
);
2592 ASM_OUTPUT_LABEL (stream
, name
);
2593 ASM_OUTPUT_SKIP (stream
, size
? size
: 1);
2597 #undef TARGET_ASM_FILE_END
2598 #define TARGET_ASM_FILE_END msp430_file_end
2600 /* Emit MSPABI and GNU object attributes.
2601 Tags and values for MSPABI attributes are:
2602 OFBA_MSPABI_Tag_ISA 4
2605 OFBA_MSPABI_Tag_Code_Model 6
2608 OFBA_MSPABI_Tag_Data_Model 8
2611 Restricted 3 (Unused by GNU)
2612 OFBA_MSPABI_Tag_enum_size 10 (Unused by GNU)
2613 Note that Code_Model and Data_Model are always equal for GNU.
2614 We define a new .gnu_attribute to keep track of the data region used.
2615 Tag_GNU_MSP430_Data_Region 4
2618 See binutils-gdb/include/elf/msp430.h for the full details. */
2620 msp430_file_end (void)
2622 #ifdef HAVE_AS_MSPABI_ATTRIBUTE
2623 /* Enum for tag names. */
2626 OFBA_MSPABI_Tag_ISA
= 4,
2627 OFBA_MSPABI_Tag_Code_Model
= 6,
2628 OFBA_MSPABI_Tag_Data_Model
= 8,
2629 Tag_GNU_MSP430_Data_Region
= 4
2631 /* Enum for tag values. */
2634 OFBA_MSPABI_Val_ISA_MSP430
= 1,
2635 OFBA_MSPABI_Val_ISA_MSP430X
= 2,
2636 OFBA_MSPABI_Val_Model_Small
= 1,
2637 OFBA_MSPABI_Val_Model_Large
= 2,
2638 Tag_GNU_MSP430_Data_Region_Lower
= 1,
2639 Tag_GNU_MSP430_Data_Region_Any
= 2
2641 /* .mspabi_attribute is a GNU assembler directive only. The assembler will
2642 construct a .MSP430.attributes section based on the options it is invoked
2643 with. The values it reads from these directives are used for validating
2645 const char *msp430_attr
= ".mspabi_attribute";
2646 const char *gnu_attr
= ".gnu_attribute";
2648 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_ISA. */
2649 fprintf (asm_out_file
, "\t%s %d, %d\n", msp430_attr
, OFBA_MSPABI_Tag_ISA
,
2650 msp430x
? OFBA_MSPABI_Val_ISA_MSP430X
: OFBA_MSPABI_Val_ISA_MSP430
);
2651 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Code_Model. */
2652 fprintf (asm_out_file
, "\t%s %d, %d\n", msp430_attr
,
2653 OFBA_MSPABI_Tag_Code_Model
,
2654 TARGET_LARGE
? OFBA_MSPABI_Val_Model_Large
2655 : OFBA_MSPABI_Val_Model_Small
);
2656 /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Data_Model. */
2657 fprintf (asm_out_file
, "\t%s %d, %d\n", msp430_attr
,
2658 OFBA_MSPABI_Tag_Data_Model
,
2659 TARGET_LARGE
? OFBA_MSPABI_Val_Model_Large
2660 : OFBA_MSPABI_Val_Model_Small
);
2661 #ifdef HAVE_AS_GNU_ATTRIBUTE
2662 /* Emit .gnu_attribute directive for Tag_GNU_MSP430_Data_Region. */
2663 fprintf (asm_out_file
, "\t%s %d, %d\n", gnu_attr
, Tag_GNU_MSP430_Data_Region
,
2664 msp430_data_region
== MSP430_REGION_LOWER
2665 ? Tag_GNU_MSP430_Data_Region_Lower
2666 : Tag_GNU_MSP430_Data_Region_Any
);
2673 MSP430_BUILTIN_BIC_SR
,
2674 MSP430_BUILTIN_BIS_SR
,
2675 MSP430_BUILTIN_DELAY_CYCLES
,
2679 static GTY(()) tree msp430_builtins
[(int) MSP430_BUILTIN_max
];
2682 msp430_init_builtins (void)
2684 tree void_ftype_int
= build_function_type_list (void_type_node
,
2685 integer_type_node
, NULL
);
2686 tree void_ftype_longlong
2687 = build_function_type_list (void_type_node
, long_long_integer_type_node
,
2690 msp430_builtins
[MSP430_BUILTIN_BIC_SR
] =
2691 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int
,
2692 MSP430_BUILTIN_BIC_SR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
2694 msp430_builtins
[MSP430_BUILTIN_BIS_SR
] =
2695 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int
,
2696 MSP430_BUILTIN_BIS_SR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
2698 msp430_builtins
[MSP430_BUILTIN_DELAY_CYCLES
] =
2699 add_builtin_function ( "__delay_cycles", void_ftype_longlong
,
2700 MSP430_BUILTIN_DELAY_CYCLES
, BUILT_IN_MD
, NULL
,
2705 msp430_builtin_decl (unsigned code
, bool initialize ATTRIBUTE_UNUSED
)
2709 case MSP430_BUILTIN_BIC_SR
:
2710 case MSP430_BUILTIN_BIS_SR
:
2711 case MSP430_BUILTIN_DELAY_CYCLES
:
2712 return msp430_builtins
[code
];
2714 return error_mark_node
;
2718 /* These constants are really register reads, which are faster than
2719 regular constants. */
2721 cg_magic_constant (HOST_WIDE_INT c
)
2739 msp430_expand_delay_cycles (rtx arg
)
2741 HOST_WIDE_INT i
, c
, n
;
2742 /* extra cycles for MSP430X instructions */
2743 #define CYCX(M,X) (msp430x ? (X) : (M))
2745 if (GET_CODE (arg
) != CONST_INT
)
2747 error ("%<__delay_cycles%> only takes constant arguments");
2753 if (HOST_BITS_PER_WIDE_INT
> 32)
2757 error ("%<__delay_cycles%> only takes non-negative cycle counts");
2762 emit_insn (gen_delay_cycles_start (arg
));
2764 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
2765 if (c
> 3 * 0xffff + CYCX (7, 10))
2768 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long
2769 (x<=0xffff) loop. */
2770 if (c
>= 0x10000 * 7 + CYCX (14, 16))
2773 c
-= CYCX (14, 16) + 7 * 0x10000;
2776 if ((unsigned long long) i
> 0xffffffffULL
)
2778 error ("%<__delay_cycles%> is limited to 32-bit loop counts");
2784 i
= (c
- CYCX (14, 16)) / 7;
2785 c
-= CYCX (14, 16) + i
* 7;
2788 if (cg_magic_constant (i
& 0xffff))
2790 if (cg_magic_constant ((i
>> 16) & 0xffff))
2794 emit_insn (gen_delay_cycles_32x (GEN_INT (i
), GEN_INT (n
- c
)));
2796 emit_insn (gen_delay_cycles_32 (GEN_INT (i
), GEN_INT (n
- c
)));
2799 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is
2804 i
= (c
- CYCX (7, 10)) / 3;
2805 c
-= CYCX (7, 10) + i
* 3;
2807 if (cg_magic_constant (i
))
2811 emit_insn (gen_delay_cycles_16x (GEN_INT (i
), GEN_INT (n
- c
)));
2813 emit_insn (gen_delay_cycles_16 (GEN_INT (i
), GEN_INT (n
- c
)));
2818 emit_insn (gen_delay_cycles_2 ());
2824 emit_insn (gen_delay_cycles_1 ());
2828 emit_insn (gen_delay_cycles_end (arg
));
2834 msp430_expand_builtin (tree exp
,
2835 rtx target ATTRIBUTE_UNUSED
,
2836 rtx subtarget ATTRIBUTE_UNUSED
,
2837 machine_mode mode ATTRIBUTE_UNUSED
,
2838 int ignore ATTRIBUTE_UNUSED
)
2840 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2841 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
2842 rtx arg1
= expand_normal (CALL_EXPR_ARG (exp
, 0));
2844 if (fcode
== MSP430_BUILTIN_DELAY_CYCLES
)
2845 return msp430_expand_delay_cycles (arg1
);
2847 if (! msp430_is_interrupt_func ())
2849 error ("MSP430 built-in functions only work inside interrupt handlers");
2853 if (! REG_P (arg1
) && ! CONSTANT_P (arg1
))
2854 arg1
= force_reg (mode
, arg1
);
2858 case MSP430_BUILTIN_BIC_SR
: emit_insn (gen_bic_SR (arg1
)); break;
2859 case MSP430_BUILTIN_BIS_SR
: emit_insn (gen_bis_SR (arg1
)); break;
2861 internal_error ("bad builtin code");
2867 #undef TARGET_INIT_BUILTINS
2868 #define TARGET_INIT_BUILTINS msp430_init_builtins
2870 #undef TARGET_EXPAND_BUILTIN
2871 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
2873 #undef TARGET_BUILTIN_DECL
2874 #define TARGET_BUILTIN_DECL msp430_builtin_decl
2877 msp430_expand_prologue (void)
2881 /* Always use stack_pointer_rtx instead of calling
2882 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
2883 that there is a single rtx representing the stack pointer,
2884 namely stack_pointer_rtx, and uses == to recognize it. */
2885 rtx sp
= stack_pointer_rtx
;
2888 if (is_naked_func ())
2890 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2891 examines the output of the gen_prologue() function. */
2892 emit_insn (gen_rtx_CLOBBER (VOIDmode
, GEN_INT (0)));
2896 emit_insn (gen_prologue_start_marker ());
2898 if (is_critical_func ())
2900 emit_insn (gen_push_intr_state ());
2901 emit_insn (gen_disable_interrupts ());
2903 else if (is_reentrant_func ())
2904 emit_insn (gen_disable_interrupts ());
2906 if (!cfun
->machine
->computed
)
2907 msp430_compute_frame_info ();
2909 if (flag_stack_usage_info
)
2910 current_function_static_stack_size
= cfun
->machine
->framesize
;
2912 if (crtl
->args
.pretend_args_size
)
2916 gcc_assert (crtl
->args
.pretend_args_size
== 2);
2918 p
= emit_insn (gen_grow_and_swap ());
2920 /* Document the stack decrement... */
2921 note
= F (gen_rtx_SET (stack_pointer_rtx
,
2922 gen_rtx_MINUS (Pmode
,
2923 stack_pointer_rtx
, GEN_INT (2))));
2924 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
2926 /* ...and the establishment of a new location for the return address. */
2927 note
= F (gen_rtx_SET (gen_rtx_MEM (Pmode
,
2928 gen_rtx_PLUS (Pmode
,
2932 add_reg_note (p
, REG_CFA_OFFSET
, note
);
2936 for (i
= 15; i
>= 4; i
--)
2937 if (cfun
->machine
->need_to_save
[i
])
2939 /* We need to save COUNT sequential registers starting from regnum
2944 for (seq
= i
- 1; seq
>= 4 && cfun
->machine
->need_to_save
[seq
]; seq
--)
2950 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two
2952 p
= F (emit_insn (gen_pushm (gen_rtx_REG (Pmode
, i
),
2955 /* Document the stack decrement as a result of PUSHM. */
2956 note
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (count
+ 1));
2958 XVECEXP (note
, 0, 0)
2959 = F (gen_rtx_SET (stack_pointer_rtx
,
2960 gen_rtx_PLUS (Pmode
,
2962 GEN_INT (count
* (TARGET_LARGE
2965 /* *sp-- = R[i-j] */
2969 for (j
= 0; j
< count
; j
++)
2972 int ofs
= (count
- j
- 1) * (TARGET_LARGE
? 4 : 2);
2975 addr
= gen_rtx_PLUS (Pmode
, sp
, GEN_INT (ofs
));
2977 addr
= stack_pointer_rtx
;
2979 XVECEXP (note
, 0, j
+ 1) =
2980 F (gen_rtx_SET (gen_rtx_MEM (Pmode
, addr
),
2981 gen_rtx_REG (Pmode
, i
- j
)));
2984 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
2988 F (emit_insn (gen_push (gen_rtx_REG (Pmode
, i
))));
2991 if (frame_pointer_needed
)
2992 F (emit_move_insn (gen_rtx_REG (Pmode
, FRAME_POINTER_REGNUM
), sp
));
2994 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
2996 increment_stack (- fs
);
2998 emit_insn (gen_prologue_end_marker ());
3002 msp430_expand_epilogue (int is_eh
)
3006 rtx sp
= stack_pointer_rtx
;
3010 if (is_naked_func ())
3012 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
3013 examines the output of the gen_epilogue() function. */
3014 emit_insn (gen_rtx_CLOBBER (VOIDmode
, GEN_INT (0)));
3018 if (cfun
->machine
->need_to_save
[10])
3020 /* Check for a helper function. */
3021 helper_n
= 7; /* For when the loop below never sees a match. */
3022 for (i
= 9; i
>= 4; i
--)
3023 if (!cfun
->machine
->need_to_save
[i
])
3027 if (cfun
->machine
->need_to_save
[i
])
3036 emit_insn (gen_epilogue_start_marker ());
3038 if (cfun
->decl
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun
->decl
)),
3040 emit_insn (gen_msp430_refsym_need_exit ());
3042 if (is_wakeup_func ())
3043 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
3044 status register current residing on the stack. When this function
3045 executes its RETI instruction the SR will be updated with this saved
3046 value, thus ensuring that the processor is woken up from any low power
3047 state in which it may be residing. */
3048 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
3050 fs
= cfun
->machine
->framesize_locals
+ cfun
->machine
->framesize_outgoing
;
3052 increment_stack (fs
);
3056 /* We need to add the right "SP" register save just after the
3057 regular ones, so that when we pop it off we're in the EH
3058 return frame, not this one. This overwrites our own return
3059 address, but we're not going to be returning anyway. */
3060 rtx r12
= gen_rtx_REG (Pmode
, 12);
3061 rtx (*addPmode
)(rtx
, rtx
, rtx
) = TARGET_LARGE
? gen_addpsi3
: gen_addhi3
;
3063 /* R12 will hold the new SP. */
3064 i
= cfun
->machine
->framesize_regs
;
3065 emit_move_insn (r12
, stack_pointer_rtx
);
3066 emit_insn (addPmode (r12
, r12
, EH_RETURN_STACKADJ_RTX
));
3067 emit_insn (addPmode (r12
, r12
, GEN_INT (i
)));
3068 emit_move_insn (gen_rtx_MEM (Pmode
, plus_constant (Pmode
,
3073 for (i
= 4; i
<= 15; i
++)
3074 if (cfun
->machine
->need_to_save
[i
])
3076 /* We need to restore COUNT sequential registers starting from regnum
3080 int helper_used
= 0;
3085 for (seq
= i
+ 1; seq
<= 15 && cfun
->machine
->need_to_save
[seq
];
3093 /* Note: With TARGET_LARGE we still use
3094 POPM as POPX.A is two bytes bigger. */
3095 p
= F (emit_insn (gen_popm (stack_pointer_rtx
, GEN_INT (seq
- 1),
3098 else if (i
== 11 - helper_n
3099 && ! msp430_is_interrupt_func ()
3100 && ! is_reentrant_func ()
3101 && ! is_critical_func ()
3102 && crtl
->args
.pretend_args_size
== 0
3103 /* Calling the helper takes as many bytes as the POP;RET
3108 p
= F (emit_jump_insn (gen_epilogue_helper (GEN_INT (helper_n
))));
3113 p
= F (emit_insn (gen_pop (gen_rtx_REG (Pmode
, i
))));
3115 /* Document the stack increment as a result of POPM. */
3116 note
= gen_rtx_SEQUENCE (VOIDmode
, rtvec_alloc (count
+ 1));
3118 addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3119 GEN_INT (count
* (TARGET_LARGE
? 4 : 2)));
3121 XVECEXP (note
, 0, 0) = F (gen_rtx_SET (stack_pointer_rtx
, addr
));
3124 /* *sp++ = R[i+j] */
3128 for (j
= 0; j
< count
; j
++)
3130 int ofs
= j
* (TARGET_LARGE
? 4 : 2);
3133 addr
= gen_rtx_PLUS (Pmode
, sp
, GEN_INT (ofs
));
3135 addr
= stack_pointer_rtx
;
3137 XVECEXP (note
, 0, j
+ 1)
3138 = F (gen_rtx_SET (gen_rtx_MEM (Pmode
, addr
),
3139 gen_rtx_REG (Pmode
, i
+ j
)));
3141 add_reg_note (p
, REG_FRAME_RELATED_EXPR
, note
);
3150 /* Also pop SP, which puts us into the EH return frame. Except
3151 that you can't "pop" sp, you have to just load it off the
3153 emit_move_insn (stack_pointer_rtx
, gen_rtx_MEM (Pmode
,
3154 stack_pointer_rtx
));
3157 if (crtl
->args
.pretend_args_size
)
3158 emit_insn (gen_swap_and_shrink ());
3160 if (is_critical_func ())
3161 emit_insn (gen_pop_intr_state ());
3162 else if (is_reentrant_func ())
3163 emit_insn (gen_enable_interrupts ());
3165 emit_jump_insn (gen_msp430_return ());
3168 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
3169 m32c_emit_eh_epilogue. */
3171 msp430_eh_return_stackadj_rtx (void)
3173 if (!cfun
->machine
->eh_stack_adjust
)
3177 sa
= gen_rtx_REG (Pmode
, 15);
3178 cfun
->machine
->eh_stack_adjust
= sa
;
3180 return cfun
->machine
->eh_stack_adjust
;
3183 /* This function is called before reload, to "fix" the stack in
3184 preparation for an EH return. */
3186 msp430_expand_eh_return (rtx eh_handler
)
3188 /* These are all Pmode */
3189 rtx ap
, sa
, ra
, tmp
;
3191 ap
= arg_pointer_rtx
;
3192 sa
= msp430_eh_return_stackadj_rtx ();
3196 tmp
= gen_rtx_PLUS (Pmode
, ap
, sa
);
3197 tmp
= plus_constant (Pmode
, tmp
, TARGET_LARGE
? -4 : -2);
3198 tmp
= gen_rtx_MEM (Pmode
, tmp
);
3199 emit_move_insn (tmp
, ra
);
3202 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
3203 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
3205 msp430_init_dwarf_reg_sizes_extra (tree address
)
3208 rtx addr
= expand_normal (address
);
3209 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
3211 /* This needs to match msp430_unwind_word_mode (above). */
3215 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
3217 unsigned int dnum
= DWARF_FRAME_REGNUM (i
);
3218 unsigned int rnum
= DWARF2_FRAME_REG_OUT (dnum
, 1);
3220 if (rnum
< DWARF_FRAME_REGISTERS
)
3222 HOST_WIDE_INT offset
= rnum
* GET_MODE_SIZE (QImode
);
3224 emit_move_insn (adjust_address (mem
, QImode
, offset
),
3225 gen_int_mode (4, QImode
));
3230 /* The MSP430 ABI defines a number of helper functions that should be
3231 used for, for example, 32-bit shifts. This function is called to
3232 emit such a function, using the table above to optimize some
3235 msp430_expand_helper (rtx
*operands
, const char *helper_name
,
3236 bool const_variants
)
3238 rtx c
, fusage
, fsym
;
3239 char *helper_const
= NULL
;
3243 machine_mode arg0mode
= GET_MODE (operands
[0]);
3244 machine_mode arg1mode
= GET_MODE (operands
[1]);
3245 machine_mode arg2mode
= GET_MODE (operands
[2]);
3246 int expand_mpy
= startswith (helper_name
, "__mspabi_mpy");
3247 /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a
3249 gcc_assert (!(expand_mpy
&& const_variants
));
3251 if (arg1mode
!= VOIDmode
&& arg2mode
!= VOIDmode
)
3252 /* Modes of arguments must be equal if not constants. */
3253 gcc_assert (arg1mode
== arg2mode
);
3255 if (arg1mode
== VOIDmode
)
3256 arg1mode
= arg0mode
;
3257 if (arg2mode
== VOIDmode
)
3258 arg2mode
= arg0mode
;
3260 if (arg1mode
== SImode
)
3265 else if (arg1mode
== DImode
)
3272 /* Use the "const_variant" of a shift library function if requested.
3273 These are faster, but have larger code size. */
3275 && CONST_INT_P (operands
[2])
3276 && INTVAL (operands
[2]) >= 1
3277 && INTVAL (operands
[2]) <= 15)
3279 /* Note that the INTVAL is limited in value and length by the conditional
3281 int len
= strlen (helper_name
) + 4;
3282 helper_const
= (char *) xmalloc (len
);
3283 snprintf (helper_const
, len
, "%s_%d", helper_name
,
3284 (int) INTVAL (operands
[2]));
3287 /* Setup the arguments to the helper function. */
3288 emit_move_insn (gen_rtx_REG (arg1mode
, arg1
),
3291 emit_move_insn (gen_rtx_REG (arg2mode
, arg2
),
3296 if (msp430_use_f5_series_hwmult ())
3297 fsym
= gen_rtx_SYMBOL_REF (VOIDmode
, concat (helper_name
,
3299 else if (msp430_use_32bit_hwmult ())
3301 /* When the arguments are 16-bits, the 16-bit hardware multiplier is
3303 if (arg1mode
== HImode
)
3304 fsym
= gen_rtx_SYMBOL_REF (VOIDmode
, concat (helper_name
,
3307 fsym
= gen_rtx_SYMBOL_REF (VOIDmode
, concat (helper_name
,
3310 else if (msp430_use_16bit_hwmult ())
3311 fsym
= gen_rtx_SYMBOL_REF (VOIDmode
, concat (helper_name
,
3314 fsym
= gen_rtx_SYMBOL_REF (VOIDmode
, helper_name
);
3317 fsym
= gen_rtx_SYMBOL_REF (VOIDmode
,
3318 helper_const
? helper_const
: helper_name
);
3320 c
= gen_call_value_internal (gen_rtx_REG (arg0mode
, 12), fsym
, GEN_INT (0));
3322 c
= emit_call_insn (c
);
3323 RTL_CONST_CALL_P (c
) = 1;
3325 /* Add register usage information for the arguments to the call. */
3327 use_regs (&fusage
, arg1
, arg1sz
);
3330 /* If we are expanding a shift, we only need to use the low register
3331 for the shift amount. */
3333 use_regs (&fusage
, arg2
, 1);
3335 use_regs (&fusage
, arg2
, arg1sz
);
3337 add_function_usage_to (c
, fusage
);
3339 emit_move_insn (operands
[0],
3340 /* Return value will always start in R12. */
3341 gen_rtx_REG (arg0mode
, 12));
3344 /* Return TRUE if the helper function should be used and FALSE if the shifts
3345 insns should be emitted inline. */
3347 use_helper_for_const_shift (machine_mode mode
, HOST_WIDE_INT amt
)
3349 const int default_inline_shift
= 4;
3350 /* We initialize the option to 65 so we know if the user set it or not. */
3351 int user_set_max_inline
= (msp430_max_inline_shift
== 65 ? 0 : 1);
3352 int max_inline
= (user_set_max_inline
? msp430_max_inline_shift
3353 : default_inline_shift
);
3354 /* 32-bit shifts are roughly twice as costly as 16-bit shifts so we adjust
3355 the heuristic accordingly. */
3356 int max_inline_32
= max_inline
/ 2;
3358 if (mode
== E_DImode
)
3361 /* Don't use helpers for these modes on 430X, when optimizing for speed, or
3362 when emitting a small number of insns. */
3363 if ((mode
== E_QImode
|| mode
== E_HImode
|| mode
== E_PSImode
)
3365 /* If the user set max_inline then we always obey that number.
3366 Otherwise we always emit the shifts inline at -O2 and above. */
3367 || amt
<= max_inline
3368 || (!user_set_max_inline
3369 && (optimize
>= 2 && !optimize_size
))))
3372 /* 430 and 430X codegen for SImode shifts is the same.
3373 Set a hard limit of 15 for the number of shifts that will be emitted
3374 inline by default, even at -O2 and above, to prevent code size
3376 if (mode
== E_SImode
3377 && (amt
<= max_inline_32
3378 || (!user_set_max_inline
3379 && (optimize
>= 2 && !optimize_size
)
3386 /* For shift operations which will use an mspabi helper function, setup the
3387 call to msp430_expand helper. Return 1 to indicate we have finished with
3388 this insn and invoke "DONE".
3389 Otherwise return 0 to indicate the insn should fallthrough.
3392 msp430_expand_shift (enum rtx_code code
, machine_mode mode
, rtx
*operands
)
3394 /* Always use the helper function when the shift amount is not a
3396 if (!CONST_INT_P (operands
[2])
3398 || use_helper_for_const_shift (mode
, INTVAL (operands
[2])))
3400 const char *helper_name
= NULL
;
3401 /* The const variants of mspabi shifts have significantly larger code
3402 size than the generic version, so use the generic version if
3403 optimizing for size. */
3404 bool const_variant
= !optimize_size
;
3408 helper_name
= (code
== ASHIFT
? "__mspabi_slli" :
3409 (code
== ASHIFTRT
? "__mspabi_srai" :
3410 (code
== LSHIFTRT
? "__mspabi_srli" :
3414 helper_name
= (code
== ASHIFT
? "__gnu_mspabi_sllp" :
3415 (code
== ASHIFTRT
? "__gnu_mspabi_srap" :
3416 (code
== LSHIFTRT
? "__gnu_mspabi_srlp" :
3418 /* No const variant for PSImode shifts FIXME. */
3419 const_variant
= false;
3422 helper_name
= (code
== ASHIFT
? "__mspabi_slll" :
3423 (code
== ASHIFTRT
? "__mspabi_sral" :
3424 (code
== LSHIFTRT
? "__mspabi_srll" :
3428 helper_name
= (code
== ASHIFT
? "__mspabi_sllll" :
3429 (code
== ASHIFTRT
? "__mspabi_srall" :
3430 (code
== LSHIFTRT
? "__mspabi_srlll" :
3432 /* No const variant for DImode shifts. */
3433 const_variant
= false;
3439 gcc_assert (helper_name
);
3440 msp430_expand_helper (operands
, helper_name
, const_variant
);
3443 /* When returning 0, there must be an insn to match the RTL pattern
3444 otherwise there will be an unrecognizeable insn. */
3448 /* Helper function to emit a sequence of shift instructions. The amount of
3449 shift instructions to emit is in OPERANDS[2].
3450 For 430 we output copies of identical inline shifts for all modes.
3451 For 430X it is inneficient to do so for any modes except SI and DI, since we
3452 can make use of R*M insns or RPT with 430X insns, so this function is only
3453 used for SImode in that case. */
3455 msp430_output_asm_shift_insns (enum rtx_code code
, machine_mode mode
,
3456 rtx
*operands
, bool return_length
)
3460 int max_shift
= GET_MODE_BITSIZE (mode
) - 1;
3463 gcc_assert (CONST_INT_P (operands
[2]));
3464 amt
= INTVAL (operands
[2]);
3466 if (amt
== 0 || amt
> max_shift
)
3473 output_asm_insn ("# ignored undefined behaviour left shift "
3474 "of %1 by %2", operands
);
3477 output_asm_insn ("# ignored undefined behaviour arithmetic right "
3478 "shift of %1 by %2", operands
);
3481 output_asm_insn ("# ignored undefined behaviour logical right shift "
3482 "of %1 by %2", operands
);
3492 if (!msp430x
&& mode
== HImode
)
3495 length
= 2 + (MEM_P (operands
[0]) ? 2 : 0);
3497 for (i
= 0; i
< amt
; i
++)
3498 output_asm_insn ("RLA.W\t%0", operands
);
3500 else if (mode
== SImode
)
3503 length
= 4 + (MEM_P (operands
[0]) ? 4 : 0)
3504 + (4 * msp430x_insn_required (operands
[0]));
3506 for (i
= 0; i
< amt
; i
++)
3507 output_asm_insn ("RLA%X0.W\t%L0 { RLC%X0.W\t%H0", operands
);
3510 /* Catch unhandled cases. */
3513 else if (code
== ASHIFTRT
)
3515 if (!msp430x
&& mode
== HImode
)
3518 length
= 2 + (MEM_P (operands
[0]) ? 2 : 0);
3520 for (i
= 0; i
< amt
; i
++)
3521 output_asm_insn ("RRA.W\t%0", operands
);
3523 else if (mode
== SImode
)
3526 length
= 4 + (MEM_P (operands
[0]) ? 4 : 0)
3527 + (4 * msp430x_insn_required (operands
[0]));
3529 for (i
= 0; i
< amt
; i
++)
3530 output_asm_insn ("RRA%X0.W\t%H0 { RRC%X0.W\t%L0", operands
);
3535 else if (code
== LSHIFTRT
)
3537 if (!msp430x
&& mode
== HImode
)
3540 length
= 4 + (MEM_P (operands
[0]) ? 2 : 0);
3542 for (i
= 0; i
< amt
; i
++)
3543 output_asm_insn ("CLRC { RRC.W\t%0", operands
);
3545 else if (mode
== SImode
)
3548 length
= 6 + (MEM_P (operands
[0]) ? 4 : 0)
3549 + (4 * msp430x_insn_required (operands
[0]));
3551 for (i
= 0; i
< amt
; i
++)
3552 output_asm_insn ("CLRC { RRC%X0.W\t%H0 { RRC%X0.W\t%L0",
3555 /* FIXME: Why doesn't "RRUX.W\t%H0 { RRC%X0.W\t%L0" work for msp430x?
3556 It causes execution timeouts e.g. pr41963.c. */
3558 else if (msp430x
&& mode
== SImode
)
3563 for (i
= 0; i
< amt
; i
++)
3564 output_asm_insn ("RRUX.W\t%H0 { RRC%X0.W\t%L0", operands
);
3570 return length
* amt
;
3573 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
3575 msp430_fixup_compare_operands (machine_mode my_mode
, rtx
* operands
)
3577 /* constants we're looking for, not constants which are allowed. */
3578 int const_op_idx
= 1;
3580 if (msp430_reversible_cmp_operator (operands
[0], VOIDmode
))
3583 if (GET_CODE (operands
[const_op_idx
]) != REG
3584 && GET_CODE (operands
[const_op_idx
]) != MEM
)
3585 operands
[const_op_idx
] = copy_to_mode_reg (my_mode
, operands
[const_op_idx
]);
3588 /* Simplify_gen_subreg() doesn't handle memory references the way we
3589 need it to below, so we use this function for when we must get a
3590 valid subreg in a "natural" state. */
3592 msp430_subreg (machine_mode mode
, rtx r
, machine_mode omode
, int byte
)
3595 gcc_assert (mode
== HImode
);
3597 if (GET_CODE (r
) == SUBREG
3598 && SUBREG_BYTE (r
) == 0)
3600 rtx ireg
= SUBREG_REG (r
);
3601 machine_mode imode
= GET_MODE (ireg
);
3603 /* special case for (HI (SI (PSI ...), 0)) */
3604 if (imode
== PSImode
3607 rv
= gen_rtx_SUBREG (mode
, ireg
, byte
);
3609 rv
= simplify_gen_subreg (mode
, ireg
, imode
, byte
);
3611 else if (GET_CODE (r
) == MEM
)
3613 /* When byte == 2, we can be certain that we were already called with an
3614 identical rtx with byte == 0. So we don't need to do anything to
3615 get a 2 byte offset of a (mem (post_inc)) rtx, since the address has
3616 already been offset by the post_inc itself. */
3617 if (GET_CODE (XEXP (r
, 0)) == POST_INC
&& byte
== 2)
3619 rv
= adjust_address (r
, mode
, byte
);
3621 else if (GET_CODE (r
) == SYMBOL_REF
3622 && (byte
== 0 || byte
== 2)
3625 rv
= gen_rtx_ZERO_EXTRACT (HImode
, r
, GEN_INT (16), GEN_INT (8*byte
));
3626 rv
= gen_rtx_CONST (HImode
, r
);
3629 rv
= simplify_gen_subreg (mode
, r
, omode
, byte
);
3638 msp430_split_addsi (rtx
*operands
)
3640 operands
[3] = msp430_subreg (HImode
, operands
[0], SImode
, 0);
3641 operands
[4] = msp430_subreg (HImode
, operands
[1], SImode
, 0);
3642 operands
[5] = msp430_subreg (HImode
, operands
[2], SImode
, 0);
3643 operands
[6] = msp430_subreg (HImode
, operands
[0], SImode
, 2);
3644 operands
[7] = msp430_subreg (HImode
, operands
[1], SImode
, 2);
3645 operands
[8] = msp430_subreg (HImode
, operands
[2], SImode
, 2);
3647 /* BZ 64160: Do not use this splitter when the dest partially overlaps the
3649 if (reg_overlap_mentioned_p (operands
[3], operands
[7])
3650 || reg_overlap_mentioned_p (operands
[3], operands
[8]))
3653 if (GET_CODE (operands
[5]) == CONST_INT
)
3654 operands
[9] = GEN_INT (INTVAL (operands
[5]) & 0xffff);
3655 /* Handle post_inc, for example:
3658 (mem:SI (post_inc:PSI (reg:PSI))))). */
3659 else if (MEM_P (operands
[5]) && GET_CODE (XEXP (operands
[5], 0)) == POST_INC
)
3661 /* Strip out the post_inc from (mem (post_inc (reg))). */
3662 operands
[9] = XEXP (XEXP (operands
[5], 0), 0);
3663 operands
[9] = gen_rtx_MEM (HImode
, operands
[9]);
3664 /* Then zero extend as normal. */
3665 operands
[9] = gen_rtx_ZERO_EXTEND (SImode
, operands
[9]);
3668 operands
[9] = gen_rtx_ZERO_EXTEND (SImode
, operands
[5]);
3672 /* Called by movsi_x to generate the HImode operands. */
3674 msp430_split_movsi (rtx
*operands
)
3676 rtx op00
, op02
, op10
, op12
;
3678 op00
= msp430_subreg (HImode
, operands
[0], SImode
, 0);
3679 op02
= msp430_subreg (HImode
, operands
[0], SImode
, 2);
3681 if (GET_CODE (operands
[1]) == CONST
3682 || GET_CODE (operands
[1]) == SYMBOL_REF
)
3684 op10
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16),
3686 op10
= gen_rtx_CONST (HImode
, op10
);
3687 op12
= gen_rtx_ZERO_EXTRACT (HImode
, operands
[1], GEN_INT (16),
3689 op12
= gen_rtx_CONST (HImode
, op12
);
3693 op10
= msp430_subreg (HImode
, operands
[1], SImode
, 0);
3694 op12
= msp430_subreg (HImode
, operands
[1], SImode
, 2);
3697 if (rtx_equal_p (operands
[0], operands
[1]))
3704 else if (rtx_equal_p (op00
, op12
)
3705 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
3706 || (REG_P (op00
) && reg_mentioned_p (op00
, op10
))
3707 /* Or storing (rN) into mem (rN). */
3708 || (REG_P (op10
) && reg_mentioned_p (op10
, op00
)))
3725 /* The MSPABI specifies the names of various helper functions, many of
3726 which are compatible with GCC's helpers. This table maps the GCC
3727 name to the MSPABI name. */
3730 char const * const gcc_name
;
3731 char const * const ti_name
;
3733 helper_function_name_mappings
[] =
3735 /* Floating point to/from integer conversions. */
3736 { "__truncdfsf2", "__mspabi_cvtdf" },
3737 { "__extendsfdf2", "__mspabi_cvtfd" },
3738 { "__fixdfhi", "__mspabi_fixdi" },
3739 { "__fixdfsi", "__mspabi_fixdli" },
3740 { "__fixdfdi", "__mspabi_fixdlli" },
3741 { "__fixunsdfhi", "__mspabi_fixdu" },
3742 { "__fixunsdfsi", "__mspabi_fixdul" },
3743 { "__fixunsdfdi", "__mspabi_fixdull" },
3744 { "__fixsfhi", "__mspabi_fixfi" },
3745 { "__fixsfsi", "__mspabi_fixfli" },
3746 { "__fixsfdi", "__mspabi_fixflli" },
3747 { "__fixunsfhi", "__mspabi_fixfu" },
3748 { "__fixunsfsi", "__mspabi_fixful" },
3749 { "__fixunsfdi", "__mspabi_fixfull" },
3750 { "__floathisf", "__mspabi_fltif" },
3751 { "__floatsisf", "__mspabi_fltlif" },
3752 { "__floatdisf", "__mspabi_fltllif" },
3753 { "__floathidf", "__mspabi_fltid" },
3754 { "__floatsidf", "__mspabi_fltlid" },
3755 { "__floatdidf", "__mspabi_fltllid" },
3756 { "__floatunhisf", "__mspabi_fltuf" },
3757 { "__floatunsisf", "__mspabi_fltulf" },
3758 { "__floatundisf", "__mspabi_fltullf" },
3759 { "__floatunhidf", "__mspabi_fltud" },
3760 { "__floatunsidf", "__mspabi_fltuld" },
3761 { "__floatundidf", "__mspabi_fltulld" },
3763 /* Floating point comparisons. */
3764 /* GCC uses individual functions for each comparison, TI uses one
3765 compare <=> function. */
3767 /* Floating point arithmetic. */
3768 { "__adddf3", "__mspabi_addd" },
3769 { "__addsf3", "__mspabi_addf" },
3770 { "__divdf3", "__mspabi_divd" },
3771 { "__divsf3", "__mspabi_divf" },
3772 { "__muldf3", "__mspabi_mpyd" },
3773 { "__mulsf3", "__mspabi_mpyf" },
3774 { "__subdf3", "__mspabi_subd" },
3775 { "__subsf3", "__mspabi_subf" },
3776 /* GCC does not use helper functions for negation. */
3778 /* Integer multiply, divide, remainder. */
3779 { "__mulhi3", "__mspabi_mpyi" },
3780 { "__mulsi3", "__mspabi_mpyl" },
3781 { "__muldi3", "__mspabi_mpyll" },
3783 /* Clarify signed vs unsigned first. */
3784 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
3786 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
3790 { "__divhi3", "__mspabi_divi" },
3791 { "__divsi3", "__mspabi_divli" },
3792 { "__divdi3", "__mspabi_divlli" },
3793 { "__udivhi3", "__mspabi_divu" },
3794 { "__udivsi3", "__mspabi_divul" },
3795 { "__udivdi3", "__mspabi_divull" },
3796 { "__modhi3", "__mspabi_remi" },
3797 { "__modsi3", "__mspabi_remli" },
3798 { "__moddi3", "__mspabi_remlli" },
3799 { "__umodhi3", "__mspabi_remu" },
3800 { "__umodsi3", "__mspabi_remul" },
3801 { "__umoddi3", "__mspabi_remull" },
3803 /* Bitwise operations. */
3804 /* Rotation - no rotation support yet. */
3805 /* Logical left shift - gcc already does these itself. */
3806 /* Arithmetic left shift - gcc already does these itself. */
3807 /* Arithmetic right shift - gcc already does these itself. */
3812 /* Returns true if the current MCU supports an F5xxx series
3813 hardware multiper. */
3816 msp430_use_f5_series_hwmult (void)
3818 static const char * cached_match
= NULL
;
3819 static bool cached_result
;
3821 if (msp430_hwmult_type
== MSP430_HWMULT_F5SERIES
)
3824 if (target_mcu
== NULL
|| msp430_hwmult_type
!= MSP430_HWMULT_AUTO
)
3827 if (target_mcu
== cached_match
)
3828 return cached_result
;
3830 cached_match
= target_mcu
;
3832 if (strncasecmp (target_mcu
, "msp430f5", 8) == 0)
3833 return cached_result
= true;
3834 if (strncasecmp (target_mcu
, "msp430fr5", 9) == 0)
3835 return cached_result
= true;
3836 if (strncasecmp (target_mcu
, "msp430f6", 8) == 0)
3837 return cached_result
= true;
3839 msp430_extract_mcu_data (target_mcu
);
3841 if (extracted_mcu_data
.name
!= NULL
)
3842 return cached_result
= extracted_mcu_data
.hwmpy
== 8;
3844 return cached_result
= false;
3847 /* Returns true if the current MCU has a second generation
3848 32-bit hardware multiplier. */
3851 msp430_use_32bit_hwmult (void)
3853 static const char * cached_match
= NULL
;
3854 static bool cached_result
;
3856 if (msp430_hwmult_type
== MSP430_HWMULT_LARGE
)
3859 if (target_mcu
== NULL
|| msp430_hwmult_type
!= MSP430_HWMULT_AUTO
)
3862 if (target_mcu
== cached_match
)
3863 return cached_result
;
3865 cached_match
= target_mcu
;
3867 msp430_extract_mcu_data (target_mcu
);
3868 if (extracted_mcu_data
.name
!= NULL
)
3869 return cached_result
= extracted_mcu_data
.hwmpy
== 4;
3871 return cached_result
= false;
3874 /* Returns true if the current MCU has a first generation
3875 16-bit hardware multiplier. */
3878 msp430_use_16bit_hwmult (void)
3880 static const char * cached_match
= NULL
;
3881 static bool cached_result
;
3883 if (msp430_hwmult_type
== MSP430_HWMULT_SMALL
)
3886 if (target_mcu
== NULL
|| msp430_hwmult_type
!= MSP430_HWMULT_AUTO
)
3889 if (target_mcu
== cached_match
)
3890 return cached_result
;
3892 cached_match
= target_mcu
;
3894 msp430_extract_mcu_data (target_mcu
);
3895 if (extracted_mcu_data
.name
!= NULL
)
3896 return cached_result
= (extracted_mcu_data
.hwmpy
== 1
3897 || extracted_mcu_data
.hwmpy
== 2);
3899 return cached_result
= false;
3902 /* Returns true if the current MCU does not have a
3903 hardware multiplier of any kind. */
3906 msp430_has_hwmult (void)
3908 static const char * cached_match
= NULL
;
3909 static bool cached_result
;
3911 if (msp430_hwmult_type
== MSP430_HWMULT_NONE
)
3914 /* TRUE for any other explicit hwmult specified. */
3915 if (msp430_hwmult_type
!= MSP430_HWMULT_AUTO
)
3918 /* Now handle -mhwmult=auto. */
3919 if (target_mcu
== NULL
)
3922 if (target_mcu
== cached_match
)
3923 return cached_result
;
3925 cached_match
= target_mcu
;
3927 msp430_extract_mcu_data (target_mcu
);
3928 if (extracted_mcu_data
.name
!= NULL
)
3929 return cached_result
= extracted_mcu_data
.hwmpy
!= 0;
3931 /* If we do not recognise the MCU name, we assume that it does not support
3932 any kind of hardware multiply - this is the safest assumption to make. */
3933 return cached_result
= false;
3936 /* This function does the same as the default, but it will replace GCC
3937 function names with the MSPABI-specified ones. */
3940 msp430_output_labelref (FILE *file
, const char *name
)
3944 for (i
= 0; helper_function_name_mappings
[i
].gcc_name
; i
++)
3945 if (strcmp (helper_function_name_mappings
[i
].gcc_name
, name
) == 0)
3947 name
= helper_function_name_mappings
[i
].ti_name
;
3951 if (user_label_prefix
[0] != 0)
3952 fputs (user_label_prefix
, file
);
3957 /* Common code for msp430_print_operand... */
3960 msp430_print_operand_raw (FILE * file
, rtx op
)
3964 switch (GET_CODE (op
))
3967 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
3973 fprintf (file
, "%#" HOST_WIDE_INT_PRINT
"x", i
);
3975 fprintf (file
, "%" HOST_WIDE_INT_PRINT
"d", i
);
3983 output_addr_const (file
, op
);
3987 print_rtl (file
, op
);
3992 #undef TARGET_ASM_ALIGNED_PSI_OP
3993 #define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
3994 #undef TARGET_ASM_UNALIGNED_PSI_OP
3995 #define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
3997 #undef TARGET_PRINT_OPERAND_ADDRESS
3998 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
4000 /* Output to stdio stream FILE the assembler syntax for an
4001 instruction operand that is a memory reference whose address
4005 msp430_print_operand_addr (FILE * file
, machine_mode
/*mode*/, rtx addr
)
4007 switch (GET_CODE (addr
))
4010 msp430_print_operand_raw (file
, XEXP (addr
, 1));
4011 gcc_assert (REG_P (XEXP (addr
, 0)));
4012 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
4016 fprintf (file
, "@");
4020 fprintf (file
, "@%s+", reg_names
[REGNO (XEXP (addr
, 0))]);
4027 fprintf (file
, "&");
4034 msp430_print_operand_raw (file
, addr
);
4037 /* We can only allow signed 15-bit indexes i.e. +/-32K. */
4039 msp430_check_index_not_high_mem (rtx op
)
4041 if (CONST_INT_P (op
)
4042 && IN_RANGE (INTVAL (op
), HOST_WIDE_INT_M1U
<< 15, (1 << 15) - 1))
4047 /* If this returns true, we don't need a 430X insn. */
4049 msp430_check_plus_not_high_mem (rtx op
)
4051 if (GET_CODE (op
) != PLUS
)
4053 rtx op0
= XEXP (op
, 0);
4054 rtx op1
= XEXP (op
, 1);
4055 if (SYMBOL_REF_P (op0
)
4056 && (SYMBOL_REF_FLAGS (op0
) & SYMBOL_FLAG_LOW_MEM
)
4057 && msp430_check_index_not_high_mem (op1
))
4062 /* Determine whether an RTX is definitely not a MEM referencing an address in
4063 the upper memory region. Returns true if we've decided the address will be
4064 in the lower memory region, or the RTX is not a MEM. Returns false
4066 The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
4067 involving a symbol_ref here. */
4069 msp430_op_not_in_high_mem (rtx op
)
4073 if (!TARGET_LARGE
|| !MEM_P (op
))
4078 if (SYMBOL_REF_P (op0
) && (SYMBOL_REF_FLAGS (op0
) & SYMBOL_FLAG_LOW_MEM
))
4079 /* msp430_encode_section_info decided this mem will be in lower
4083 /* Check possibilites for (mem (plus)).
4084 e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2. */
4085 if (msp430_check_plus_not_high_mem (op0
)
4086 || ((GET_CODE (op0
) == CONST
)
4087 && msp430_check_plus_not_high_mem (XEXP (op0
, 0))))
4090 /* An absolute 16-bit address is allowed. */
4091 if ((CONST_INT_P (op0
) && (IN_RANGE (INTVAL (op0
), 0, (1 << 16) - 1))))
4094 /* Return false when undecided. */
4098 /* Based on the operand OP, is a 430X insn required to handle it?
4099 There are only 3 conditions for which a 430X insn is required:
4101 - memory reference to a symbol which could be in upper memory
4102 (so its address is > 0xFFFF)
4103 - absolute address which has VOIDmode, i.e. (mem:HI (const_int))
4104 Use a 430 insn if none of these conditions are true. */
4106 msp430x_insn_required (rtx op
)
4108 return (GET_MODE (op
) == PSImode
4109 || !msp430_op_not_in_high_mem (op
));
4112 #undef TARGET_PRINT_OPERAND
4113 #define TARGET_PRINT_OPERAND msp430_print_operand
4115 /* A Select low 16-bits of the constant/register/memory operand.
4116 B Select high 16-bits of the constant/register/memory
4118 C Select bits 32-47 of the constant/register/memory operand.
4119 D Select bits 48-63 of the constant/register/memory operand.
4120 H Equivalent to @code{B} (for backwards compatibility).
4121 I Print the inverse (logical @code{NOT}) of the constant
4123 J Print an integer without a @code{#} prefix.
4124 L Equivalent to @code{A} (for backwards compatibility).
4125 O Offset of the current frame from the top of the stack.
4126 Q Use the @code{A} instruction postfix.
4127 R Inverse of condition code, for unsigned comparisons.
4128 W Subtract 16 from the constant value.
4129 X Use the @code{X} instruction postfix.
4130 Y Subtract 4 from the constant value.
4131 Z Subtract 1 from the constant value.
4132 b Append @code{.B}, @code{.W} or @code{.A} to the
4133 instruction, depending on the mode.
4134 d Offset 1 byte of a memory reference or constant value.
4135 e Offset 3 bytes of a memory reference or constant value.
4136 f Offset 5 bytes of a memory reference or constant value.
4137 g Offset 7 bytes of a memory reference or constant value.
4138 p Print the value of 2, raised to the power of the given
4139 constant. Used to select the specified bit position.
4140 r Inverse of condition code, for signed comparisons.
4141 x Equivialent to @code{X}, but only for pointers. */
4144 msp430_print_operand (FILE * file
, rtx op
, int letter
)
4147 /* These are used by the 'A', 'B', 'C', 'D', 'd', 'e', 'f' and 'g' modifiers
4148 to describe how to process the operand to get the requested value. */
4151 int const_shift
= 0;
4153 /* We can't use c, n, a, or l. */
4157 gcc_assert (CONST_INT_P (op
));
4158 /* Print the constant value, less one. */
4159 fprintf (file
, "#%ld", (long) (INTVAL (op
) - 1));
4162 gcc_assert (CONST_INT_P (op
));
4163 /* Print the constant value, less four. */
4164 fprintf (file
, "#%ld", (long) (INTVAL (op
) - 4));
4167 gcc_assert (CONST_INT_P (op
));
4168 /* Print the constant value, less 16. */
4169 fprintf (file
, "#%ld", (long) (INTVAL (op
) - 16));
4172 if (GET_CODE (op
) == CONST_INT
)
4174 /* Inverse of constants */
4175 int i
= INTVAL (op
);
4176 fprintf (file
, "%d", ~i
);
4181 case 'r': /* Conditional jump where the condition is reversed. */
4182 switch (GET_CODE (op
))
4184 case EQ
: fprintf (file
, "NE"); break;
4185 case NE
: fprintf (file
, "EQ"); break;
4186 case GEU
: fprintf (file
, "LO"); break;
4187 case LTU
: fprintf (file
, "HS"); break;
4188 case GE
: fprintf (file
, "L"); break;
4189 case LT
: fprintf (file
, "GE"); break;
4190 /* Assume these have reversed operands. */
4191 case GTU
: fprintf (file
, "HS"); break;
4192 case LEU
: fprintf (file
, "LO"); break;
4193 case GT
: fprintf (file
, "GE"); break;
4194 case LE
: fprintf (file
, "L"); break;
4196 msp430_print_operand_raw (file
, op
);
4200 case 'R': /* Conditional jump where the operands are reversed. */
4201 switch (GET_CODE (op
))
4203 case GTU
: fprintf (file
, "LO"); break;
4204 case LEU
: fprintf (file
, "HS"); break;
4205 case GT
: fprintf (file
, "L"); break;
4206 case LE
: fprintf (file
, "GE"); break;
4208 msp430_print_operand_raw (file
, op
);
4212 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
4213 gcc_assert (CONST_INT_P (op
));
4214 fprintf (file
, "#%d", 1 << INTVAL (op
));
4217 switch (GET_MODE (op
))
4219 case E_QImode
: fprintf (file
, ".B"); return;
4220 case E_HImode
: fprintf (file
, ".W"); return;
4221 case E_PSImode
: fprintf (file
, ".A"); return;
4222 case E_SImode
: fprintf (file
, ".A"); return;
4226 case 'd': case 'e': case 'f': case 'g':
4229 output_operand_lossage ("%%d, %%e, %%f, %%g operand modifiers are "
4230 "for memory references or constant values "
4235 case 'B': case 'H': /* high half */
4277 case 'A': case 'L': /* Low half. */
4278 switch (GET_CODE (op
))
4281 /* We don't need to adjust the address for post_inc. */
4282 op
= adjust_address (op
, Pmode
,
4283 (GET_CODE (XEXP (op
, 0)) == POST_INC
)
4287 op
= gen_rtx_REG (Pmode
, REGNO (op
) + reg_off
);
4290 op
= GEN_INT (((long long) INTVAL (op
) >> const_shift
) & 0xffff);
4294 /* If you get here, figure out a test case :-) */
4300 /* This is used to turn, for example, an ADD opcode into an ADDX
4301 opcode when we're using 20-bit addresses.
4302 This can be used for insns which have only one operand which might be
4304 If an insn has two different operands which could be memory operands,
4305 then the "Yx" constraint must be used to determine if the X suffix is
4306 required by checking both operands. */
4307 if (GET_MODE (op
) == PSImode
4308 || !msp430_op_not_in_high_mem (op
))
4309 fprintf (file
, "X");
4313 /* Similarly, but only for PSImodes. BIC, and other insn patterns using
4314 the QHI mode iterator (which includes, QI, HI, and PSImode) use
4316 if (GET_MODE (op
) == PSImode
)
4317 fprintf (file
, "X");
4321 /* Likewise, for BR -> BRA. */
4323 fprintf (file
, "A");
4327 /* Computes the offset to the top of the stack for the current frame.
4328 This has to be done here rather than in, say, msp430_expand_builtin()
4329 because builtins are expanded before the frame layout is
4331 fprintf (file
, "%d",
4332 msp430_initial_elimination_offset (ARG_POINTER_REGNUM
,
4333 STACK_POINTER_REGNUM
)
4334 - (TARGET_LARGE
? 4 : 2));
4338 gcc_assert (GET_CODE (op
) == CONST_INT
);
4342 output_operand_lossage ("invalid operand prefix");
4346 switch (GET_CODE (op
))
4349 msp430_print_operand_raw (file
, op
);
4353 addr
= XEXP (op
, 0);
4354 msp430_print_operand_addr (file
, GET_MODE (op
), addr
);
4358 if (GET_CODE (XEXP (op
, 0)) == ZERO_EXTRACT
)
4361 switch (INTVAL (XEXP (op
, 2)))
4364 fprintf (file
, "#lo (");
4365 msp430_print_operand_raw (file
, XEXP (op
, 0));
4366 fprintf (file
, ")");
4370 fprintf (file
, "#hi (");
4371 msp430_print_operand_raw (file
, XEXP (op
, 0));
4372 fprintf (file
, ")");
4376 output_operand_lossage ("invalid zero extract");
4386 fprintf (file
, "#");
4387 msp430_print_operand_raw (file
, op
);
4390 case EQ
: fprintf (file
, "EQ"); break;
4391 case NE
: fprintf (file
, "NE"); break;
4392 case GEU
: fprintf (file
, "HS"); break;
4393 case LTU
: fprintf (file
, "LO"); break;
4394 case GE
: fprintf (file
, "GE"); break;
4395 case LT
: fprintf (file
, "L"); break;
4398 print_rtl (file
, op
);
4407 msp430_return_addr_rtx (int count
)
4413 ra_size
= TARGET_LARGE
? 4 : 2;
4414 if (crtl
->args
.pretend_args_size
)
4417 return gen_rtx_MEM (Pmode
, gen_rtx_PLUS (Pmode
, arg_pointer_rtx
,
4418 GEN_INT (- ra_size
)));
4422 msp430_incoming_return_addr_rtx (void)
4424 return gen_rtx_MEM (Pmode
, stack_pointer_rtx
);
4427 /* If the path to the MSP430-GCC support files has been found by examining
4428 an environment variable (see msp430_check_env_var_for_devices in
4429 msp430-devices.cc), or -mdevices-csv-loc=, register this path as an include
4430 directory so the user can #include msp430.h without needing to specify the
4431 path to the support files with -I. */
4433 msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED
,
4434 const char *iprefix ATTRIBUTE_UNUSED
,
4435 int stdinc ATTRIBUTE_UNUSED
)
4438 if (msp430_devices_csv_loc
)
4439 include_dir
= xstrdup (msp430_devices_csv_loc
);
4440 else if (msp430_check_env_var_for_devices (&include_dir
))
4442 include_dir
= msp430_dirname (include_dir
);
4444 include_dir
= update_path (include_dir
, "");
4445 add_path (include_dir
, INC_SYSTEM
, false, false);
4448 /* Instruction generation stuff. */
4450 /* Generate a sequence of instructions to sign-extend an HI
4451 value into an SI value. Handles the tricky case where
4452 we are overwriting the destination.
4453 Return the number of bytes used by the emitted instructions.
4454 If RETURN_LENGTH is true then do not emit the assembly instruction
4457 msp430x_extendhisi (rtx
* operands
, bool return_length
)
4459 if (REGNO (operands
[0]) == REGNO (operands
[1]))
4461 /* Low word of dest == source word. */
4463 output_asm_insn ("BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
4469 /* Note: This sequence is approximately the same length as invoking a
4470 helper function to perform the sign-extension, as in:
4474 CALL __mspabi_srai_15
4477 but this version does not involve any function calls or using argument
4478 registers, so it reduces register pressure. */
4480 output_asm_insn ("MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
4484 else if (REGNO (operands
[0]) + 1 == REGNO (operands
[1]))
4486 /* High word of dest == source word. */
4488 output_asm_insn ("MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0",
4493 /* No overlap between dest and source. */
4495 output_asm_insn ("MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0",
4500 /* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */
4502 #undef TARGET_CAN_CHANGE_MODE_CLASS
4503 #define TARGET_CAN_CHANGE_MODE_CLASS msp430_can_change_mode_class
4506 msp430_can_change_mode_class (machine_mode from
, machine_mode to
, reg_class_t
)
4508 if ((to
== PSImode
&& from
== SImode
)
4509 || (to
== SImode
&& from
== PSImode
)
4510 || (to
== DImode
&& from
== PSImode
)
4511 || (to
== PSImode
&& from
== DImode
))
4516 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
4517 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
4519 #undef TARGET_DOCUMENTATION_NAME
4520 #define TARGET_DOCUMENTATION_NAME "MSP430"
4522 struct gcc_target targetm
= TARGET_INITIALIZER
;
4524 #include "gt-msp430.h"