* config/msp430/msp430.c (msp430_expand_epilogue): Fix compile
[official-gcc.git] / gcc / config / msp430 / msp430.c
blobae6e6a91492d92e8aaf0f11a08b06c1360a35ac5
1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "libfuncs.h"
38 #include "recog.h"
39 #include "diagnostic-core.h"
40 #include "toplev.h"
41 #include "reload.h"
42 #include "df.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "debug.h"
46 #include "target.h"
47 #include "target-def.h"
48 #include "langhooks.h"
49 #include "msp430-protos.h"
50 #include "dumpfile.h"
51 #include "opts.h"
55 static void msp430_compute_frame_info (void);
59 /* Run-time Target Specification */
61 bool msp430x = false;
63 struct GTY(()) machine_function
65 /* If set, the rest of the fields have been computed. */
66 int computed;
67 /* Which registers need to be saved in the pro/epilogue. */
68 int need_to_save [FIRST_PSEUDO_REGISTER];
70 /* These fields describe the frame layout... */
71 /* arg pointer */
72 /* 2/4 bytes for saved PC */
73 int framesize_regs;
74 /* frame pointer */
75 int framesize_locals;
76 int framesize_outgoing;
77 /* stack pointer */
78 int framesize;
80 /* How much we adjust the stack when returning from an exception
81 handler. */
82 rtx eh_stack_adjust;
85 /* This is our init_machine_status, as set in
86 msp_option_override. */
87 static struct machine_function *
88 msp430_init_machine_status (void)
90 struct machine_function *m;
92 m = ggc_alloc_cleared_machine_function ();
94 return m;
97 #undef TARGET_HANDLE_OPTION
98 #define TARGET_HANDLE_OPTION msp430_handle_option
100 bool
101 msp430_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
102 struct gcc_options *opts_set ATTRIBUTE_UNUSED,
103 const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
104 location_t loc ATTRIBUTE_UNUSED)
106 return true;
109 #undef TARGET_OPTION_OVERRIDE
110 #define TARGET_OPTION_OVERRIDE msp430_option_override
112 static void
113 msp430_option_override (void)
115 init_machine_status = msp430_init_machine_status;
117 if (target_cpu
118 && (strstr (target_cpu, "430x")
119 || strstr (target_cpu, "430X")))
120 msp430x = true;
122 if (TARGET_LARGE && !msp430x)
123 error ("-mlarge requires a 430X-compatible -mmcu=");
125 if (flag_exceptions || flag_non_call_exceptions
126 || flag_unwind_tables || flag_asynchronous_unwind_tables)
127 flag_omit_frame_pointer = false;
128 else
129 flag_omit_frame_pointer = true;
131 /* This is a hack to work around a problem with the newlib build
132 mechanism. Newlib always appends CFLAGS to the end of the GCC
133 command line and always sets -O2 in CFLAGS. Thus it is not
134 possible to build newlib with -Os enabled. Until now... */
135 if (TARGET_OPT_SPACE && optimize < 3)
136 optimize_size = 1;
141 /* Storage Layout */
143 #undef TARGET_MS_BITFIELD_LAYOUT_P
144 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
146 bool
147 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
149 return false;
154 /* Register Usage */
156 /* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single
157 PSImode value, but not an SImode value. */
159 msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
160 enum machine_mode mode)
162 if (mode == PSImode && msp430x)
163 return 1;
164 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
165 / UNITS_PER_WORD);
168 /* Implements HARD_REGNO_MODE_OK. */
170 msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED,
171 enum machine_mode mode)
173 return regno <= (ARG_POINTER_REGNUM - msp430_hard_regno_nregs (regno, mode));
176 /* Implements MODES_TIEABLE_P. */
177 bool
178 msp430_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
180 if ((mode1 == PSImode || mode2 == SImode)
181 || (mode1 == SImode || mode2 == PSImode))
182 return false;
184 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
185 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
186 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
187 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
190 #undef TARGET_FRAME_POINTER_REQUIRED
191 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
193 static bool
194 msp430_frame_pointer_required (void)
196 return false;
199 #undef TARGET_CAN_ELIMINATE
200 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
202 static bool
203 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
204 const int to_reg ATTRIBUTE_UNUSED)
206 return true;
209 /* Implements INITIAL_ELIMINATION_OFFSET. */
211 msp430_initial_elimination_offset (int from, int to)
213 int rv = 0; /* As if arg to arg. */
215 msp430_compute_frame_info ();
217 switch (to)
219 case STACK_POINTER_REGNUM:
220 rv += cfun->machine->framesize_outgoing;
221 rv += cfun->machine->framesize_locals;
222 /* Fall through. */
223 case FRAME_POINTER_REGNUM:
224 rv += cfun->machine->framesize_regs;
225 /* Allow for the saved return address. */
226 rv += (TARGET_LARGE ? 4 : 2);
227 /* NB/ No need to allow for crtl->args.pretend_args_size.
228 GCC does that for us. */
229 break;
230 default:
231 gcc_unreachable ();
234 switch (from)
236 case FRAME_POINTER_REGNUM:
237 /* Allow for the fall through above. */
238 rv -= (TARGET_LARGE ? 4 : 2);
239 rv -= cfun->machine->framesize_regs;
240 case ARG_POINTER_REGNUM:
241 break;
242 default:
243 gcc_unreachable ();
246 return rv;
249 /* Named Address Space support */
252 /* Return the appropriate mode for a named address pointer. */
253 #undef TARGET_ADDR_SPACE_POINTER_MODE
254 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
255 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
256 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
258 static enum machine_mode
259 msp430_addr_space_pointer_mode (addr_space_t addrspace)
261 switch (addrspace)
263 default:
264 case ADDR_SPACE_GENERIC:
265 return Pmode;
266 case ADDR_SPACE_NEAR:
267 return HImode;
268 case ADDR_SPACE_FAR:
269 return PSImode;
273 /* Function pointers are stored in unwind_word sized
274 variables, so make sure that unwind_word is big enough. */
275 #undef TARGET_UNWIND_WORD_MODE
276 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
278 static enum machine_mode
279 msp430_unwind_word_mode (void)
281 return TARGET_LARGE ? SImode : HImode;
284 /* Determine if one named address space is a subset of another. */
285 #undef TARGET_ADDR_SPACE_SUBSET_P
286 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
287 static bool
288 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
290 if (subset == superset)
291 return true;
292 else
293 return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR);
296 #undef TARGET_ADDR_SPACE_CONVERT
297 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
298 /* Convert from one address space to another. */
299 static rtx
300 msp430_addr_space_convert (rtx op, tree from_type, tree to_type)
302 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
303 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
304 rtx result;
306 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
308 /* This is unpredictable, as we're truncating off usable address
309 bits. */
311 if (CONSTANT_P (op))
312 return gen_rtx_CONST (HImode, op);
314 result = gen_reg_rtx (HImode);
315 emit_insn (gen_truncpsihi2 (result, op));
316 return result;
318 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
320 /* This always works. */
322 if (CONSTANT_P (op))
323 return gen_rtx_CONST (PSImode, op);
325 result = gen_reg_rtx (PSImode);
326 emit_insn (gen_zero_extendhipsi2 (result, op));
327 return result;
329 else
330 gcc_unreachable ();
333 /* Stack Layout and Calling Conventions. */
335 /* For each function, we list the gcc version and the TI version on
336 each line, where we're converting the function names. */
337 static char const * const special_convention_function_names [] =
339 "__muldi3", "__mspabi_mpyll",
340 "__udivdi3", "__mspabi_divull",
341 "__umoddi3", "__mspabi_remull",
342 "__divdi3", "__mspabi_divlli",
343 "__moddi3", "__mspabi_remlli",
344 "__mspabi_srall",
345 "__mspabi_srlll",
346 "__mspabi_sllll",
347 "__adddf3", "__mspabi_addd",
348 "__subdf3", "__mspabi_subd",
349 "__muldf3", "__mspabi_mpyd",
350 "__divdf3", "__mspabi_divd",
351 "__mspabi_cmpd",
352 NULL
355 /* TRUE if the function passed is a "speical" function. Special
356 functions pass two DImode parameters in registers. */
357 static bool
358 msp430_special_register_convention_p (const char *name)
360 int i;
362 for (i = 0; special_convention_function_names [i]; i++)
363 if (! strcmp (name, special_convention_function_names [i]))
364 return true;
366 return false;
369 #undef TARGET_FUNCTION_VALUE_REGNO_P
370 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
372 bool
373 msp430_function_value_regno_p (unsigned int regno)
375 return regno == 12;
379 #undef TARGET_FUNCTION_VALUE
380 #define TARGET_FUNCTION_VALUE msp430_function_value
383 msp430_function_value (const_tree ret_type,
384 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
385 bool outgoing ATTRIBUTE_UNUSED)
387 return gen_rtx_REG (TYPE_MODE (ret_type), 12);
390 #undef TARGET_LIBCALL_VALUE
391 #define TARGET_LIBCALL_VALUE msp430_libcall_value
394 msp430_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
396 return gen_rtx_REG (mode, 12);
399 /* Implements INIT_CUMULATIVE_ARGS. */
400 void
401 msp430_init_cumulative_args (CUMULATIVE_ARGS *ca,
402 tree fntype ATTRIBUTE_UNUSED,
403 rtx libname ATTRIBUTE_UNUSED,
404 tree fndecl ATTRIBUTE_UNUSED,
405 int n_named_args ATTRIBUTE_UNUSED)
407 const char *fname;
408 memset (ca, 0, sizeof(*ca));
410 ca->can_split = 1;
412 if (fndecl)
413 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
414 else if (libname)
415 fname = XSTR (libname, 0);
416 else
417 fname = NULL;
419 if (fname && msp430_special_register_convention_p (fname))
420 ca->special_p = 1;
423 /* Helper function for argument passing; this function is the common
424 code that determines where an argument will be passed. */
425 static void
426 msp430_evaluate_arg (cumulative_args_t cap,
427 enum machine_mode mode,
428 const_tree type ATTRIBUTE_UNUSED,
429 bool named)
431 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
432 int nregs = GET_MODE_SIZE (mode);
433 int i;
435 ca->reg_count = 0;
436 ca->mem_count = 0;
438 if (!named)
439 return;
441 if (mode == PSImode)
442 nregs = 1;
443 else
444 nregs = (nregs + 1) / 2;
446 if (ca->special_p)
448 /* Function is passed two DImode operands, in R8:R11 and
449 R12:15. */
450 ca->start_reg = 8;
451 ca->reg_count = 4;
452 return;
455 switch (nregs)
457 case 1:
458 for (i = 0; i < 4; i++)
459 if (! ca->reg_used [i])
461 ca->reg_count = 1;
462 ca->start_reg = CA_FIRST_REG + i;
463 return;
465 break;
466 case 2:
467 for (i = 0; i < 3; i++)
468 if (! ca->reg_used [i] && ! ca->reg_used [i + 1])
470 ca->reg_count = 2;
471 ca->start_reg = CA_FIRST_REG + i;
472 return;
474 if (! ca->reg_used [3] && ca->can_split)
476 ca->reg_count = 1;
477 ca->mem_count = 2;
478 ca->start_reg = CA_FIRST_REG + 3;
479 return;
481 break;
482 case 3:
483 case 4:
484 ca->can_split = 0;
485 if (! ca->reg_used [0]
486 && ! ca->reg_used [1]
487 && ! ca->reg_used [2]
488 && ! ca->reg_used [3])
490 ca->reg_count = 4;
491 ca->start_reg = CA_FIRST_REG;
492 return;
494 break;
498 #undef TARGET_PROMOTE_PROTOTYPES
499 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
501 bool
502 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
504 return false;
507 #undef TARGET_FUNCTION_ARG
508 #define TARGET_FUNCTION_ARG msp430_function_arg
511 msp430_function_arg (cumulative_args_t cap,
512 enum machine_mode mode,
513 const_tree type,
514 bool named)
516 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
518 msp430_evaluate_arg (cap, mode, type, named);
520 if (ca->reg_count)
521 return gen_rtx_REG (mode, ca->start_reg);
523 return 0;
526 #undef TARGET_ARG_PARTIAL_BYTES
527 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
530 msp430_arg_partial_bytes (cumulative_args_t cap,
531 enum machine_mode mode,
532 tree type,
533 bool named)
535 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
537 msp430_evaluate_arg (cap, mode, type, named);
539 if (ca->reg_count && ca->mem_count)
540 return ca->reg_count * UNITS_PER_WORD;
542 return 0;
545 #undef TARGET_PASS_BY_REFERENCE
546 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
548 static bool
549 msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED,
550 enum machine_mode mode,
551 const_tree type,
552 bool named ATTRIBUTE_UNUSED)
554 return (mode == BLKmode
555 || (type && TREE_CODE (type) == RECORD_TYPE)
556 || (type && TREE_CODE (type) == UNION_TYPE));
559 #undef TARGET_CALLEE_COPIES
560 #define TARGET_CALLEE_COPIES msp430_callee_copies
562 static bool
563 msp430_callee_copies (cumulative_args_t cap ATTRIBUTE_UNUSED,
564 enum machine_mode mode ATTRIBUTE_UNUSED,
565 const_tree type ATTRIBUTE_UNUSED,
566 bool named ATTRIBUTE_UNUSED)
568 return true;
571 #undef TARGET_FUNCTION_ARG_ADVANCE
572 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
574 void
575 msp430_function_arg_advance (cumulative_args_t cap,
576 enum machine_mode mode,
577 const_tree type,
578 bool named)
580 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
581 int i;
583 msp430_evaluate_arg (cap, mode, type, named);
585 if (ca->start_reg >= CA_FIRST_REG)
586 for (i = 0; i < ca->reg_count; i ++)
587 ca->reg_used [i + ca->start_reg - CA_FIRST_REG] = 1;
589 ca->special_p = 0;
592 #undef TARGET_FUNCTION_ARG_BOUNDARY
593 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
595 static unsigned int
596 msp430_function_arg_boundary (enum machine_mode mode, const_tree type)
598 if (mode == BLKmode
599 && int_size_in_bytes (type) > 1)
600 return 16;
601 if (GET_MODE_BITSIZE (mode) > 8)
602 return 16;
603 return 8;
606 #undef TARGET_RETURN_IN_MEMORY
607 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
609 static bool
610 msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED)
612 enum machine_mode mode = TYPE_MODE (ret_type);
614 if (mode == BLKmode
615 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE)
616 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE))
617 return true;
619 if (GET_MODE_SIZE (mode) > 8)
620 return true;
622 return false;
625 #undef TARGET_GET_RAW_ARG_MODE
626 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
628 static enum machine_mode
629 msp430_get_raw_arg_mode (int regno)
631 return (regno == ARG_POINTER_REGNUM) ? VOIDmode : Pmode;
634 #undef TARGET_GET_RAW_RESULT_MODE
635 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
637 static enum machine_mode
638 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
640 return Pmode;
643 /* Addressing Modes */
645 #undef TARGET_LEGITIMATE_ADDRESS_P
646 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
648 static bool
649 reg_ok_for_addr (rtx r, bool strict)
651 int rn = REGNO (r);
653 if (strict && rn >= FIRST_PSEUDO_REGISTER)
654 rn = reg_renumber [rn];
655 if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
656 return true;
657 if (!strict)
658 return true;
659 return false;
662 bool
663 msp430_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
664 rtx x ATTRIBUTE_UNUSED,
665 bool strict ATTRIBUTE_UNUSED)
667 switch (GET_CODE (x))
669 case MEM:
670 return false;
672 case PLUS:
673 if (REG_P (XEXP (x, 0)))
675 if (GET_MODE (x) != GET_MODE (XEXP (x, 0)))
676 return false;
677 if (!reg_ok_for_addr (XEXP (x, 0), strict))
678 return false;
679 switch (GET_CODE (XEXP (x, 1)))
681 case CONST:
682 case SYMBOL_REF:
683 case CONST_INT:
684 return true;
685 default:
686 return false;
689 return false;
691 case REG:
692 if (!reg_ok_for_addr (x, strict))
693 return false;
694 /* else... */
695 case CONST:
696 case SYMBOL_REF:
697 case CONST_INT:
698 return true;
700 default:
701 return false;
705 #undef TARGET_LEGITIMATE_CONSTANT_P
706 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
708 static bool
709 msp430_legitimate_constant (enum machine_mode mode, rtx x)
711 return ! CONST_INT_P (x)
712 || mode != PSImode
713 /* GCC does not know the width of the PSImode, so make
714 sure that it does not try to use a constant value that
715 is out of range. */
716 || (INTVAL (x) < (1 << 20) && INTVAL (x) >= (-1 << 20));
720 #undef TARGET_RTX_COSTS
721 #define TARGET_RTX_COSTS msp430_rtx_costs
723 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED,
724 int code,
725 int outer_code ATTRIBUTE_UNUSED,
726 int opno ATTRIBUTE_UNUSED,
727 int * total,
728 bool speed ATTRIBUTE_UNUSED)
730 switch (code)
732 case SIGN_EXTEND:
733 if (GET_MODE (x) == SImode && outer_code == SET)
735 *total = COSTS_N_INSNS (4);
736 return true;
738 break;
739 case ASHIFT:
740 case ASHIFTRT:
741 case LSHIFTRT:
742 if (!msp430x)
744 *total = COSTS_N_INSNS (100);
745 return true;
747 break;
749 return false;
752 /* Function Entry and Exit */
754 /* The MSP430 call frame looks like this:
756 <higher addresses>
757 +--------------------+
759 | Stack Arguments |
761 +--------------------+ <-- "arg pointer"
763 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
765 +--------------------+
766 | SR if this func has|
767 | been called via an |
768 | interrupt. |
769 +--------------------+ <-- SP before prologue, also AP
771 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
773 +--------------------+ <-- "frame pointer"
775 | Locals |
777 +--------------------+
779 | Outgoing Args |
781 +--------------------+ <-- SP during function
782 <lower addresses>
786 /* We use this to wrap all emitted insns in the prologue, so they get
787 the "frame-related" (/f) flag set. */
788 static rtx
789 F (rtx x)
791 RTX_FRAME_RELATED_P (x) = 1;
792 return x;
795 /* This is the one spot that decides if a register is to be saved and
796 restored in the prologue/epilogue. */
797 static bool
798 msp430_preserve_reg_p (int regno)
800 /* PC, SP, SR, and the constant generator. */
801 if (regno <= 3)
802 return false;
804 /* FIXME: add interrupt, EH, etc. */
805 if (crtl->calls_eh_return)
806 return true;
808 /* Shouldn't be more than the above, but just in case... */
809 if (fixed_regs [regno])
810 return false;
812 /* Interrupt handlers save all registers they use, even
813 ones which are call saved. If they call other functions
814 then *every* register is saved. */
815 if (msp430_is_interrupt_func ())
816 return ! crtl->is_leaf || df_regs_ever_live_p (regno);
818 if (!call_used_regs [regno]
819 && df_regs_ever_live_p (regno))
820 return true;
822 return false;
825 /* Compute all the frame-related fields in our machine_function
826 structure. */
827 static void
828 msp430_compute_frame_info (void)
830 int i;
832 cfun->machine->computed = 1;
833 cfun->machine->framesize_regs = 0;
834 cfun->machine->framesize_locals = get_frame_size ();
835 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
837 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
838 if (msp430_preserve_reg_p (i))
840 cfun->machine->need_to_save [i] = 1;
841 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
843 else
844 cfun->machine->need_to_save [i] = 0;
846 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
847 cfun->machine->framesize_locals ++;
849 cfun->machine->framesize = (cfun->machine->framesize_regs
850 + cfun->machine->framesize_locals
851 + cfun->machine->framesize_outgoing);
854 static inline bool
855 is_attr_func (const char * attr)
857 return lookup_attribute (attr, DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
860 /* Returns true if the current function has the "interrupt" attribute. */
862 bool
863 msp430_is_interrupt_func (void)
865 return is_attr_func ("interrupt");
868 static inline bool
869 is_naked_func (void)
871 return is_attr_func ("naked");
874 static inline bool
875 is_reentrant_func (void)
877 return is_attr_func ("reentrant");
880 static inline bool
881 is_critical_func (void)
883 return is_attr_func ("critical");
886 #undef TARGET_ASM_FUNCTION_PROLOGUE
887 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
889 static void
890 msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
892 int r, n;
894 fprintf (outfile, "; start of function\n");
896 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
898 fprintf (outfile, "; attributes: ");
899 if (is_naked_func ())
900 fprintf (outfile, "naked ");
901 if (msp430_is_interrupt_func ())
902 fprintf (outfile, "interrupt ");
903 if (is_reentrant_func ())
904 fprintf (outfile, "reentrant ");
905 if (is_critical_func ())
906 fprintf (outfile, "critical ");
907 fprintf (outfile, "\n");
910 fprintf (outfile, "; framesize_regs: %d\n", cfun->machine->framesize_regs);
911 fprintf (outfile, "; framesize_locals: %d\n", cfun->machine->framesize_locals);
912 fprintf (outfile, "; framesize_outgoing: %d\n", cfun->machine->framesize_outgoing);
913 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
914 fprintf (outfile, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM));
915 fprintf (outfile, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM));
917 n = 0;
918 fprintf (outfile, "; saved regs:");
919 for (r = 0; r < ARG_POINTER_REGNUM; r++)
920 if (cfun->machine->need_to_save [r])
922 fprintf (outfile, " %s", reg_names [r]);
923 n = 1;
925 if (n == 0)
926 fprintf (outfile, "(none)");
927 fprintf (outfile, "\n");
930 /* Common code to change the stack pointer. */
931 static void
932 increment_stack (HOST_WIDE_INT amount)
934 rtx inc;
935 rtx sp = stack_pointer_rtx;
937 if (amount == 0)
938 return;
940 if (amount < 0)
942 inc = GEN_INT (- amount);
943 if (TARGET_LARGE)
944 F (emit_insn (gen_subpsi3 (sp, sp, inc)));
945 else
946 F (emit_insn (gen_subhi3 (sp, sp, inc)));
948 else
950 inc = GEN_INT (amount);
951 if (TARGET_LARGE)
952 emit_insn (gen_addpsi3 (sp, sp, inc));
953 else
954 emit_insn (gen_addhi3 (sp, sp, inc));
958 /* Verify MSP430 specific attributes. */
960 static tree
961 msp430_attr (tree * node,
962 tree name,
963 tree args,
964 int flags ATTRIBUTE_UNUSED,
965 bool * no_add_attrs)
967 gcc_assert (DECL_P (* node));
969 if (args != NULL)
971 tree value = TREE_VALUE (args);
973 switch (TREE_CODE (value))
975 case STRING_CST:
976 if ( strcmp (TREE_STRING_POINTER (value), "reset")
977 && strcmp (TREE_STRING_POINTER (value), "nmi")
978 && strcmp (TREE_STRING_POINTER (value), "watchdog"))
979 /* Allow the attribute to be added - the linker script
980 being used may still recognise this name. */
981 warning (OPT_Wattributes,
982 "unrecognised interrupt vector argument of %qE attribute",
983 name);
984 break;
986 case INTEGER_CST:
987 if (TREE_INT_CST_LOW (value) > 31)
988 /* Allow the attribute to be added - the linker script
989 being used may still recognise this value. */
990 warning (OPT_Wattributes,
991 "numeric argument of %qE attribute must be in range 0..31",
992 name);
993 break;
995 default:
996 warning (OPT_Wattributes,
997 "argument of %qE attribute is not a string constant or number",
998 name);
999 *no_add_attrs = true;
1000 break;
1004 if (TREE_CODE (* node) != FUNCTION_DECL)
1006 warning (OPT_Wattributes,
1007 "%qE attribute only applies to functions",
1008 name);
1009 * no_add_attrs = true;
1012 /* FIXME: We ought to check that the interrupt handler
1013 attribute has been applied to a void function. */
1014 /* FIXME: We should check that reentrant and critical
1015 functions are not naked and that critical functions
1016 are not reentrant. */
1018 return NULL_TREE;
1021 #undef TARGET_ATTRIBUTE_TABLE
1022 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1024 /* Table of MSP430-specific attributes. */
1025 const struct attribute_spec msp430_attribute_table[] =
1027 /* Name min_len decl_req, fn_type_req, affects_type_identity
1028 max_len, type_req, handler. */
1029 { "interrupt", 0, 1, true, false, false, msp430_attr, false },
1030 { "naked", 0, 0, true, false, false, msp430_attr, false },
1031 { "reentrant", 0, 0, true, false, false, msp430_attr, false },
1032 { "critical", 0, 0, true, false, false, msp430_attr, false },
1033 { NULL, 0, 0, false, false, false, NULL, false }
1036 void
1037 msp430_start_function (FILE *file, const char *name, tree decl)
1039 tree int_attr;
1041 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1042 if (int_attr != NULL_TREE)
1044 tree intr_vector = TREE_VALUE (int_attr);
1046 if (intr_vector != NULL_TREE)
1048 char buf[101];
1050 intr_vector = TREE_VALUE (intr_vector);
1052 /* The interrupt attribute has a vector value. Turn this into a
1053 section name, switch to that section and put the address of
1054 the current function into that vector slot. Note msp430_attr()
1055 has already verified the vector name for us. */
1056 if (TREE_CODE (intr_vector) == STRING_CST)
1057 sprintf (buf, "__interrupt_vector_%.80s",
1058 TREE_STRING_POINTER (intr_vector));
1059 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1060 sprintf (buf, "__interrupt_vector_%u",
1061 (unsigned int) TREE_INT_CST_LOW (intr_vector));
1063 switch_to_section (get_section (buf, SECTION_CODE, decl));
1064 fputs ("\t.word\t", file);
1065 assemble_name (file, name);
1066 fputc ('\n', file);
1067 fputc ('\t', file);
1071 switch_to_section (function_section (decl));
1072 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1075 static section *
1076 msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit)
1078 /* In large mode we must make sure that interrupt handlers are put into
1079 low memory as the vector table only accepts 16-bit addresses. */
1080 if (TARGET_LARGE
1081 && lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl)))
1082 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
1084 /* Otherwise, use the default function section. */
1085 return default_function_section (decl, freq, startup, exit);
1088 #undef TARGET_ASM_FUNCTION_SECTION
1089 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1091 enum msp430_builtin
1093 MSP430_BUILTIN_BIC_SR,
1094 MSP430_BUILTIN_BIS_SR,
1095 MSP430_BUILTIN_max
1098 static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max];
1100 static void
1101 msp430_init_builtins (void)
1103 tree void_ftype_int = build_function_type_list (void_type_node, integer_type_node, NULL);
1105 msp430_builtins[MSP430_BUILTIN_BIC_SR] =
1106 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
1107 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
1109 msp430_builtins[MSP430_BUILTIN_BIS_SR] =
1110 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
1111 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
1114 static tree
1115 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
1117 switch (code)
1119 case MSP430_BUILTIN_BIC_SR:
1120 case MSP430_BUILTIN_BIS_SR:
1121 return msp430_builtins[code];
1122 default:
1123 return error_mark_node;
1127 static rtx
1128 msp430_expand_builtin (tree exp,
1129 rtx target ATTRIBUTE_UNUSED,
1130 rtx subtarget ATTRIBUTE_UNUSED,
1131 enum machine_mode mode ATTRIBUTE_UNUSED,
1132 int ignore ATTRIBUTE_UNUSED)
1134 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
1135 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
1136 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1138 if (! msp430_is_interrupt_func ())
1140 error ("MSP430 builtin functions only work inside interrupt handlers");
1141 return NULL_RTX;
1144 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
1145 arg1 = force_reg (mode, arg1);
1147 switch (fcode)
1149 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break;
1150 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break;
1151 default:
1152 internal_error ("bad builtin code");
1153 break;
1155 return NULL_RTX;
1158 #undef TARGET_INIT_BUILTINS
1159 #define TARGET_INIT_BUILTINS msp430_init_builtins
1161 #undef TARGET_EXPAND_BUILTIN
1162 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
1164 #undef TARGET_BUILTIN_DECL
1165 #define TARGET_BUILTIN_DECL msp430_builtin_decl
1167 void
1168 msp430_expand_prologue (void)
1170 int i, j;
1171 int fs;
1172 /* Always use stack_pointer_rtx instead of calling
1173 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
1174 that there is a single rtx representing the stack pointer,
1175 namely stack_pointer_rtx, and uses == to recognize it. */
1176 rtx sp = stack_pointer_rtx;
1177 rtx p;
1179 if (is_naked_func ())
1180 return;
1182 emit_insn (gen_prologue_start_marker ());
1184 if (is_critical_func ())
1186 emit_insn (gen_push_intr_state ());
1187 emit_insn (gen_disable_interrupts ());
1189 else if (is_reentrant_func ())
1190 emit_insn (gen_disable_interrupts ());
1192 if (!cfun->machine->computed)
1193 msp430_compute_frame_info ();
1195 if (flag_stack_usage_info)
1196 current_function_static_stack_size = cfun->machine->framesize;
1198 if (crtl->args.pretend_args_size)
1200 rtx note;
1202 gcc_assert (crtl->args.pretend_args_size == 2);
1204 p = emit_insn (gen_grow_and_swap ());
1206 /* Document the stack decrement... */
1207 note = F (gen_rtx_SET (Pmode, stack_pointer_rtx,
1208 gen_rtx_MINUS (Pmode, stack_pointer_rtx, GEN_INT (2))));
1209 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
1211 /* ...and the establishment of a new location for the return address. */
1212 note = F (gen_rtx_SET (Pmode, gen_rtx_MEM (Pmode,
1213 gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-2))),
1214 pc_rtx));
1215 add_reg_note (p, REG_CFA_OFFSET, note);
1216 F (p);
1219 for (i = 15; i >= 4; i--)
1220 if (cfun->machine->need_to_save [i])
1222 int seq, count;
1223 rtx note;
1225 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
1227 count = i - seq;
1229 if (msp430x)
1231 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */
1232 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
1233 GEN_INT (count))));
1235 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
1237 XVECEXP (note, 0, 0)
1238 = F (gen_rtx_SET (VOIDmode,
1239 stack_pointer_rtx,
1240 gen_rtx_PLUS (Pmode,
1241 stack_pointer_rtx,
1242 GEN_INT (count * (TARGET_LARGE ? -4 : -2)))));
1244 /* *sp-- = R[i-j] */
1245 /* sp+N R10
1247 sp R4 */
1248 for (j = 0; j < count; j ++)
1250 rtx addr;
1251 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
1253 if (ofs)
1254 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
1255 else
1256 addr = stack_pointer_rtx;
1258 XVECEXP (note, 0, j + 1) =
1259 F (gen_rtx_SET (VOIDmode,
1260 gen_rtx_MEM (Pmode, addr),
1261 gen_rtx_REG (Pmode, i - j)) );
1264 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
1265 i -= count - 1;
1267 else
1268 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
1271 if (frame_pointer_needed)
1272 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
1274 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
1276 increment_stack (- fs);
1278 emit_insn (gen_prologue_end_marker ());
1281 void
1282 msp430_expand_epilogue (int is_eh)
1284 int i;
1285 int fs;
1286 int helper_n = 0;
1288 if (is_naked_func ())
1289 return;
1291 if (cfun->machine->need_to_save [10])
1293 /* Check for a helper function. */
1294 helper_n = 7; /* For when the loop below never sees a match. */
1295 for (i = 9; i >= 4; i--)
1296 if (!cfun->machine->need_to_save [i])
1298 helper_n = 10 - i;
1299 for (; i >= 4; i--)
1300 if (cfun->machine->need_to_save [i])
1302 helper_n = 0;
1303 break;
1305 break;
1309 emit_insn (gen_epilogue_start_marker ());
1311 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
1313 increment_stack (fs);
1315 if (is_eh)
1317 /* We need to add the right "SP" register save just after the
1318 regular ones, so that when we pop it off we're in the EH
1319 return frame, not this one. This overwrites our own return
1320 address, but we're not going to be returning anyway. */
1321 rtx r12 = gen_rtx_REG (Pmode, 12);
1322 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
1324 /* R12 will hold the new SP. */
1325 i = cfun->machine->framesize_regs;
1326 emit_move_insn (r12, stack_pointer_rtx);
1327 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
1328 emit_insn (addPmode (r12, r12, GEN_INT (i)));
1329 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, i)), r12);
1332 for (i = 4; i <= 15; i++)
1333 if (cfun->machine->need_to_save [i])
1335 int seq, count;
1337 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
1339 count = seq - i;
1341 if (msp430x)
1343 /* Note: With TARGET_LARGE we still use POPM as POPX.A is two
1344 bytes bigger.
1345 Note: See the popm pattern for the explanation of the strange
1346 arguments. */
1347 emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (~(seq - 1)),
1348 GEN_INT (count)));
1349 i += count - 1;
1351 else if (i == 11 - helper_n
1352 && ! msp430_is_interrupt_func ()
1353 && ! is_reentrant_func ()
1354 && ! is_critical_func ()
1355 && crtl->args.pretend_args_size == 0
1356 /* Calling the helper takes as many bytes as the POP;RET sequence. */
1357 && helper_n > 1
1358 && !is_eh)
1360 emit_insn (gen_epilogue_helper (GEN_INT (helper_n)));
1361 return;
1363 else
1364 emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
1367 if (is_eh)
1369 /* Also pop SP, which puts us into the EH return frame. Except
1370 that you can't "pop" sp, you have to just load it off the
1371 stack. */
1372 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode, stack_pointer_rtx));
1375 if (crtl->args.pretend_args_size)
1376 emit_insn (gen_swap_and_shrink ());
1378 if (is_critical_func ())
1379 emit_insn (gen_pop_intr_state ());
1380 else if (is_reentrant_func ())
1381 emit_insn (gen_enable_interrupts ());
1383 emit_jump_insn (gen_msp_return ());
1386 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
1387 m32c_emit_eh_epilogue. */
1389 msp430_eh_return_stackadj_rtx (void)
1391 if (!cfun->machine->eh_stack_adjust)
1393 rtx sa;
1395 sa = gen_rtx_REG (Pmode, 15);
1396 cfun->machine->eh_stack_adjust = sa;
1398 return cfun->machine->eh_stack_adjust;
1401 /* This function is called before reload, to "fix" the stack in
1402 preparation for an EH return. */
1403 void
1404 msp430_expand_eh_return (rtx eh_handler)
1406 /* These are all Pmode */
1407 rtx ap, sa, ra, tmp;
1409 ap = arg_pointer_rtx;
1410 sa = msp430_eh_return_stackadj_rtx ();
1411 ra = eh_handler;
1413 tmp = ap;
1414 tmp = gen_rtx_PLUS (Pmode, ap, sa);
1415 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
1416 tmp = gen_rtx_MEM (Pmode, tmp);
1417 emit_move_insn (tmp, ra);
1420 /* This is a list of MD patterns that implement fixed-count shifts. */
1421 static struct
1423 const char *name;
1424 int count;
1425 int need_430x;
1426 rtx (*genfunc)(rtx,rtx);
1428 const_shift_helpers[] =
1430 #define CSH(N,C,X,G) { "__mspabi_"N, C, X, gen_##G }
1432 CSH ("slli", 1, 1, slli_1),
1433 CSH ("slll", 1, 1, slll_1),
1434 CSH ("slll", 2, 1, slll_2),
1436 CSH ("srai", 1, 0, srai_1),
1437 CSH ("sral", 1, 0, sral_1),
1438 CSH ("sral", 2, 0, sral_2),
1440 CSH ("srll", 1, 0, srll_1),
1441 CSH ("srll", 2, 1, srll_2x),
1442 { 0, 0, 0, 0 }
1443 #undef CSH
1446 /* The MSP430 ABI defines a number of helper functions that should be
1447 used for, for example, 32-bit shifts. This function is called to
1448 emit such a function, using the table above to optimize some
1449 cases. */
1450 void
1451 msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants)
1453 rtx c, f;
1454 char *helper_const = NULL;
1455 int arg2 = 13;
1456 int arg1sz = 1;
1457 enum machine_mode arg0mode = GET_MODE (operands[0]);
1458 enum machine_mode arg1mode = GET_MODE (operands[1]);
1459 enum machine_mode arg2mode = GET_MODE (operands[2]);
1460 int have_430x = msp430x ? 1 : 0;
1462 if (CONST_INT_P (operands[2]))
1464 int i;
1466 for (i=0; const_shift_helpers[i].name; i++)
1468 if (const_shift_helpers[i].need_430x <= have_430x
1469 && strcmp (helper_name, const_shift_helpers[i].name) == 0
1470 && INTVAL (operands[2]) == const_shift_helpers[i].count)
1472 emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1]));
1473 return;
1478 if (arg1mode == VOIDmode)
1479 arg1mode = arg0mode;
1480 if (arg2mode == VOIDmode)
1481 arg2mode = arg0mode;
1483 if (arg1mode == SImode)
1485 arg2 = 14;
1486 arg1sz = 2;
1489 if (const_variants
1490 && CONST_INT_P (operands[2])
1491 && INTVAL (operands[2]) >= 1
1492 && INTVAL (operands[2]) <= 15)
1494 /* Note that the INTVAL is limited in value and length by the conditional above. */
1495 int len = strlen (helper_name) + 4;
1496 helper_const = (char *) xmalloc (len);
1497 snprintf (helper_const, len, "%s_%d", helper_name, (int) INTVAL (operands[2]));
1500 emit_move_insn (gen_rtx_REG (arg1mode, 12),
1501 operands[1]);
1502 if (!helper_const)
1503 emit_move_insn (gen_rtx_REG (arg2mode, arg2),
1504 operands[2]);
1506 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12),
1507 gen_rtx_SYMBOL_REF (VOIDmode, helper_const ? helper_const : helper_name),
1508 GEN_INT (0));
1509 c = emit_call_insn (c);
1510 RTL_CONST_CALL_P (c) = 1;
1512 f = 0;
1513 use_regs (&f, 12, arg1sz);
1514 if (!helper_const)
1515 use_regs (&f, arg2, 1);
1516 add_function_usage_to (c, f);
1518 emit_move_insn (operands[0],
1519 gen_rtx_REG (arg0mode, 12));
1522 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
1523 void
1524 msp430_fixup_compare_operands (enum machine_mode my_mode, rtx * operands)
1526 /* constants we're looking for, not constants which are allowed. */
1527 int const_op_idx = 1;
1529 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
1530 const_op_idx = 2;
1532 if (GET_CODE (operands[const_op_idx]) != REG
1533 && GET_CODE (operands[const_op_idx]) != MEM)
1534 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
1537 /* Simplify_gen_subreg() doesn't handle memory references the way we
1538 need it to below, so we use this function for when we must get a
1539 valid subreg in a "natural" state. */
1541 msp430_subreg (enum machine_mode mode, rtx r, enum machine_mode omode, int byte)
1543 rtx rv;
1545 if (GET_CODE (r) == SUBREG
1546 && SUBREG_BYTE (r) == 0)
1548 rtx ireg = SUBREG_REG (r);
1549 enum machine_mode imode = GET_MODE (ireg);
1551 /* special case for (HI (SI (PSI ...), 0)) */
1552 if (imode == PSImode
1553 && mode == HImode
1554 && byte == 0)
1555 rv = gen_rtx_SUBREG (mode, ireg, byte);
1556 else
1557 rv = simplify_gen_subreg (mode, ireg, imode, byte);
1559 else if (GET_CODE (r) == MEM)
1560 rv = adjust_address (r, mode, byte);
1561 else
1562 rv = simplify_gen_subreg (mode, r, omode, byte);
1564 if (!rv)
1565 gcc_unreachable ();
1567 return rv;
1570 /* Called by movsi_x to generate the HImode operands. */
1571 void
1572 msp430_split_movsi (rtx *operands)
1574 rtx op00, op02, op10, op12;
1576 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
1577 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
1579 if (GET_CODE (operands[1]) == CONST
1580 || GET_CODE (operands[1]) == SYMBOL_REF)
1582 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
1583 op10 = gen_rtx_CONST (HImode, op10);
1584 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
1585 op12 = gen_rtx_CONST (HImode, op12);
1587 else
1589 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
1590 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
1593 if (rtx_equal_p (operands[0], operands[1]))
1595 operands[2] = op02;
1596 operands[4] = op12;
1597 operands[3] = op00;
1598 operands[5] = op10;
1600 else if (rtx_equal_p (op00, op12)
1601 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
1602 || (REG_P (op00) && reg_mentioned_p (op00, op10))
1603 /* Or storing (rN) into mem (rN). */
1604 || (REG_P (op10) && reg_mentioned_p (op10, op00))
1607 operands[2] = op02;
1608 operands[4] = op12;
1609 operands[3] = op00;
1610 operands[5] = op10;
1612 else
1614 operands[2] = op00;
1615 operands[4] = op10;
1616 operands[3] = op02;
1617 operands[5] = op12;
1622 /* The MSPABI specifies the names of various helper functions, many of
1623 which are compatible with GCC's helpers. This table maps the GCC
1624 name to the MSPABI name. */
1625 static const struct
1627 char const * const gcc_name;
1628 char const * const ti_name;
1630 helper_function_name_mappings [] =
1632 /* Floating point to/from integer conversions. */
1633 { "__truncdfsf2", "__mspabi_cvtdf" },
1634 { "__extendsfdf2", "__mspabi_cvtfd" },
1635 { "__fixdfhi", "__mspabi_fixdi" },
1636 { "__fixdfsi", "__mspabi_fixdli" },
1637 { "__fixdfdi", "__mspabi_fixdlli" },
1638 { "__fixunsdfhi", "__mspabi_fixdu" },
1639 { "__fixunsdfsi", "__mspabi_fixdul" },
1640 { "__fixunsdfdi", "__mspabi_fixdull" },
1641 { "__fixsfhi", "__mspabi_fixfi" },
1642 { "__fixsfsi", "__mspabi_fixfli" },
1643 { "__fixsfdi", "__mspabi_fixflli" },
1644 { "__fixunsfhi", "__mspabi_fixfu" },
1645 { "__fixunsfsi", "__mspabi_fixful" },
1646 { "__fixunsfdi", "__mspabi_fixfull" },
1647 { "__floathisf", "__mspabi_fltif" },
1648 { "__floatsisf", "__mspabi_fltlif" },
1649 { "__floatdisf", "__mspabi_fltllif" },
1650 { "__floathidf", "__mspabi_fltid" },
1651 { "__floatsidf", "__mspabi_fltlid" },
1652 { "__floatdidf", "__mspabi_fltllid" },
1653 { "__floatunhisf", "__mspabi_fltuf" },
1654 { "__floatunsisf", "__mspabi_fltulf" },
1655 { "__floatundisf", "__mspabi_fltullf" },
1656 { "__floatunhidf", "__mspabi_fltud" },
1657 { "__floatunsidf", "__mspabi_fltuld" },
1658 { "__floatundidf", "__mspabi_fltulld" },
1660 /* Floating point comparisons. */
1661 /* GCC uses individual functions for each comparison, TI uses one
1662 compare <=> function. */
1664 /* Floating point arithmatic */
1665 { "__adddf3", "__mspabi_addd" },
1666 { "__addsf3", "__mspabi_addf" },
1667 { "__divdf3", "__mspabi_divd" },
1668 { "__divsf3", "__mspabi_divf" },
1669 { "__muldf3", "__mspabi_mpyd" },
1670 { "__mulsf3", "__mspabi_mpyf" },
1671 { "__subdf3", "__mspabi_subd" },
1672 { "__subsf3", "__mspabi_subf" },
1673 /* GCC does not use helper functions for negation */
1675 /* Integer multiply, divide, remainder. */
1676 /* Note: gcc doesn't know about hardware multiply options (yet?) */
1677 { "__mulhi3", "__mspabi_mpyi" },
1678 { "__mulsi3", "__mspabi_mpyl" },
1679 { "__muldi3", "__mspabi_mpyll" },
1680 #if 0
1681 /* Clarify signed vs unsigned first. */
1682 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */
1683 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */
1684 #endif
1686 { "__divhi3", "__mspabi_divi" },
1687 { "__divsi3", "__mspabi_divli" },
1688 { "__divdi3", "__mspabi_divlli" },
1689 { "__udivhi3", "__mspabi_divu" },
1690 { "__udivsi3", "__mspabi_divlu" },
1691 { "__udivdi3", "__mspabi_divllu" },
1692 { "__modhi3", "__mspabi_remi" },
1693 { "__modsi3", "__mspabi_remli" },
1694 { "__moddi3", "__mspabi_remlli" },
1695 { "__umodhi3", "__mspabi_remu" },
1696 { "__umodsi3", "__mspabi_remul" },
1697 { "__umoddi3", "__mspabi_remull" },
1699 /* Bitwise operations. */
1700 /* Rotation - no rotation support yet. */
1701 /* Logical left shift - gcc already does these itself. */
1702 /* Arithmetic left shift - gcc already does these itself. */
1703 /* Arithmetic right shift - gcc already does these itself. */
1705 { NULL, NULL }
1708 /* This function does the same as the default, but it will replace GCC
1709 function names with the MSPABI-specified ones. */
1710 void
1711 msp430_output_labelref (FILE *file, const char *name)
1713 int i;
1715 for (i = 0; helper_function_name_mappings [i].gcc_name; i++)
1716 if (! strcmp (helper_function_name_mappings [i].gcc_name, name))
1718 fputs (helper_function_name_mappings [i].ti_name, file);
1719 return;
1722 fputs (name, file);
1725 /* Common code for msp430_print_operand... */
1727 static void
1728 msp430_print_operand_raw (FILE * file, rtx op)
1730 int i;
1732 switch (GET_CODE (op))
1734 case REG:
1735 fprintf (file, "%s", reg_names [REGNO (op)]);
1736 break;
1738 case CONST_INT:
1739 i = INTVAL (op);
1740 if (TARGET_ASM_HEX)
1741 fprintf (file, "%#x", i);
1742 else
1743 fprintf (file, "%d", i);
1744 break;
1746 case CONST:
1747 case PLUS:
1748 case MINUS:
1749 case SYMBOL_REF:
1750 case LABEL_REF:
1751 output_addr_const (file, op);
1752 break;
1754 default:
1755 print_rtl (file, op);
1756 break;
1760 #undef TARGET_PRINT_OPERAND_ADDRESS
1761 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
1763 /* Output to stdio stream FILE the assembler syntax for an
1764 instruction operand that is a memory reference whose address
1765 is ADDR. */
1767 static void
1768 msp430_print_operand_addr (FILE * file, rtx addr)
1770 switch (GET_CODE (addr))
1772 case PLUS:
1773 msp430_print_operand_raw (file, XEXP (addr, 1));
1774 gcc_assert (REG_P (XEXP (addr, 0)));
1775 fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]);
1776 return;
1778 case REG:
1779 fprintf (file, "@");
1780 break;
1782 case CONST:
1783 case CONST_INT:
1784 case SYMBOL_REF:
1785 case LABEL_REF:
1786 fprintf (file, "&");
1787 break;
1789 default:
1790 break;
1793 msp430_print_operand_raw (file, addr);
1796 #undef TARGET_PRINT_OPERAND
1797 #define TARGET_PRINT_OPERAND msp430_print_operand
1799 static void
1800 msp430_print_operand (FILE * file, rtx op, int letter)
1802 rtx addr;
1804 /* We can't use c, n, a, or l. */
1805 switch (letter)
1807 case 'Z':
1808 gcc_assert (CONST_INT_P (op));
1809 /* Print the constant value, less one. */
1810 fprintf (file, "#%ld", INTVAL (op) - 1);
1811 return;
1812 case 'Y':
1813 gcc_assert (CONST_INT_P (op));
1814 /* Print the constant value, less four. */
1815 fprintf (file, "#%ld", INTVAL (op) - 4);
1816 return;
1817 /* case 'D': used for "decimal without '#'" */
1818 case 'I':
1819 if (GET_CODE (op) == CONST_INT)
1821 /* Inverse of constants */
1822 int i = INTVAL (op);
1823 fprintf (file, "%d", ~i);
1824 return;
1826 op = XEXP (op, 0);
1827 break;
1828 case 'r': /* Conditional jump where the condition is reversed. */
1829 switch (GET_CODE (op))
1831 case EQ: fprintf (file, "NE"); break;
1832 case NE: fprintf (file, "EQ"); break;
1833 case GEU: fprintf (file, "LO"); break;
1834 case LTU: fprintf (file, "HS"); break;
1835 case GE: fprintf (file, "L"); break;
1836 case LT: fprintf (file, "GE"); break;
1837 /* Assume these have reversed operands. */
1838 case GTU: fprintf (file, "HS"); break;
1839 case LEU: fprintf (file, "LO"); break;
1840 case GT: fprintf (file, "GE"); break;
1841 case LE: fprintf (file, "L"); break;
1842 default:
1843 msp430_print_operand_raw (file, op);
1844 break;
1846 return;
1847 case 'R': /* Conditional jump where the operands are reversed. */
1848 switch (GET_CODE (op))
1850 case GTU: fprintf (file, "LO"); break;
1851 case LEU: fprintf (file, "HS"); break;
1852 case GT: fprintf (file, "L"); break;
1853 case LE: fprintf (file, "GE"); break;
1854 default:
1855 msp430_print_operand_raw (file, op);
1856 break;
1858 return;
1859 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
1860 gcc_assert (CONST_INT_P (op));
1861 fprintf (file, "#%d", 1 << INTVAL (op));
1862 return;
1863 case 'B':
1864 switch (GET_MODE (op))
1866 case QImode: fprintf (file, ".B"); return;
1867 case HImode: fprintf (file, ".W"); return;
1868 case PSImode: fprintf (file, ".A"); return;
1869 case SImode: fprintf (file, ".A"); return;
1870 default:
1871 return;
1873 case 'L': /* Low half. */
1874 switch (GET_CODE (op))
1876 case MEM:
1877 op = adjust_address (op, Pmode, 0);
1878 break;
1879 case REG:
1880 break;
1881 case CONST_INT:
1882 op = GEN_INT (INTVAL (op) & 0xffff);
1883 letter = 0;
1884 break;
1885 default:
1886 /* If you get here, figure out a test case :-) */
1887 gcc_unreachable ();
1889 break;
1890 case 'H': /* high half */
1891 switch (GET_CODE (op))
1893 case MEM:
1894 op = adjust_address (op, Pmode, 2);
1895 break;
1896 case REG:
1897 op = gen_rtx_REG (Pmode, REGNO (op) + 1);
1898 break;
1899 case CONST_INT:
1900 op = GEN_INT (INTVAL (op) >> 16);
1901 letter = 0;
1902 break;
1903 default:
1904 /* If you get here, figure out a test case :-) */
1905 gcc_unreachable ();
1907 break;
1909 case 'X':
1910 /* This is used to turn, for example, an ADD opcode into an ADDX
1911 opcode when we're using 20-bit addresses. */
1912 if (TARGET_LARGE)
1913 fprintf (file, "X");
1914 /* We don't care which operand we use, but we want 'X' in the MD
1915 file, so we do it this way. */
1916 return;
1918 case 'x':
1919 /* Similarly, but only for PSImodes. BIC, for example, needs this. */
1920 if (TARGET_LARGE && GET_MODE (op) == PSImode)
1921 fprintf (file, "X");
1922 return;
1924 case 'A':
1925 /* Likewise, for BR -> BRA. */
1926 if (TARGET_LARGE)
1927 fprintf (file, "A");
1928 return;
1930 case 'O':
1931 /* Computes the offset to the top of the stack for the current frame.
1932 This has to be done here rather than in, say, msp430_expand_builtin()
1933 because builtins are expanded before the frame layout is determined. */
1934 fprintf (file, "%d",
1935 msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM)
1936 - 2);
1937 return;
1940 switch (GET_CODE (op))
1942 case REG:
1943 msp430_print_operand_raw (file, op);
1944 break;
1946 case MEM:
1947 addr = XEXP (op, 0);
1948 msp430_print_operand_addr (file, addr);
1949 break;
1951 case CONST_INT:
1952 case CONST:
1953 case SYMBOL_REF:
1954 case LABEL_REF:
1955 if (letter == 0)
1956 fprintf (file, "#");
1957 msp430_print_operand_raw (file, op);
1958 break;
1960 case EQ: fprintf (file, "EQ"); break;
1961 case NE: fprintf (file, "NE"); break;
1962 case GEU: fprintf (file, "HS"); break;
1963 case LTU: fprintf (file, "LO"); break;
1964 case GE: fprintf (file, "GE"); break;
1965 case LT: fprintf (file, "L"); break;
1967 default:
1968 print_rtl (file, op);
1969 break;
1974 /* Frame stuff. */
1977 msp430_return_addr_rtx (int count)
1979 int ra_size;
1980 if (count)
1981 return NULL_RTX;
1983 ra_size = TARGET_LARGE ? 4 : 2;
1984 if (crtl->args.pretend_args_size)
1985 ra_size += 2;
1987 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size)));
1991 msp430_incoming_return_addr_rtx (void)
1993 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
1996 /* Instruction generation stuff. */
1998 /* Generate a sequence of instructions to sign-extend an HI
1999 value into an SI value. Handles the tricky case where
2000 we are overwriting the destination. */
2002 const char *
2003 msp430x_extendhisi (rtx * operands)
2005 if (REGNO (operands[0]) == REGNO (operands[1]))
2006 /* Low word of dest == source word. */
2007 return "BIT.W #0x8000, %L0 { SUBC.W %H0, %H0 { INV.W %H0, %H0"; /* 8-bytes. */
2009 if (! msp430x)
2010 /* Note: This sequence is approximately the same length as invoking a helper
2011 function to perform the sign-extension, as in:
2013 MOV.W %1, %L0
2014 MOV.W %1, r12
2015 CALL __mspabi_srai_15
2016 MOV.W r12, %H0
2018 but this version does not involve any function calls or using argument
2019 registers, so it reduces register pressure. */
2020 return "MOV.W %1, %L0 { BIT.W #0x8000, %L0 { SUBC.W %H0, %H0 { INV.W %H0, %H0"; /* 10-bytes. */
2022 if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
2023 /* High word of dest == source word. */
2024 return "MOV.W %1, %L0 { RPT #15 { RRAX.W %H0"; /* 6-bytes. */
2026 /* No overlap between dest and source. */
2027 return "MOV.W %1, %L0 { MOV.W %1, %H0 { RPT #15 { RRAX.W %H0"; /* 8-bytes. */
2030 /* Likewise for logical right shifts. */
2031 const char *
2032 msp430x_logical_shift_right (rtx amount)
2034 /* The MSP430X's logical right shift instruction - RRUM - does
2035 not use an extension word, so we cannot encode a repeat count.
2036 Try various alternatives to work around this. If the count
2037 is in a register we are stuck, hence the assert. */
2038 gcc_assert (CONST_INT_P (amount));
2040 if (INTVAL (amount) <= 0
2041 || INTVAL (amount) >= 16)
2042 return "# nop logical shift.";
2044 if (INTVAL (amount) > 0
2045 && INTVAL (amount) < 5)
2046 return "rrum.w\t%2, %0"; /* Two bytes. */
2048 if (INTVAL (amount) > 4
2049 && INTVAL (amount) < 9)
2050 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
2052 /* First we logically shift right by one. Now we know
2053 that the top bit is zero and we can use the arithmetic
2054 right shift instruction to perform the rest of the shift. */
2055 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */
2058 struct gcc_target targetm = TARGET_INITIALIZER;
2060 #include "gt-msp430.h"