gcc/
[official-gcc.git] / gcc / config / msp430 / msp430.c
blob2a42c38d3fb1baab30c70592f5354f165b506cbf
1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
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 "alias.h"
26 #include "symtab.h"
27 #include "tree.h"
28 #include "fold-const.h"
29 #include "stor-layout.h"
30 #include "calls.h"
31 #include "rtl.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "function.h"
40 #include "expmed.h"
41 #include "dojump.h"
42 #include "explow.h"
43 #include "emit-rtl.h"
44 #include "varasm.h"
45 #include "stmt.h"
46 #include "expr.h"
47 #include "insn-codes.h"
48 #include "optabs.h"
49 #include "libfuncs.h"
50 #include "recog.h"
51 #include "diagnostic-core.h"
52 #include "toplev.h"
53 #include "reload.h"
54 #include "dominance.h"
55 #include "cfg.h"
56 #include "cfgrtl.h"
57 #include "cfganal.h"
58 #include "lcm.h"
59 #include "cfgbuild.h"
60 #include "cfgcleanup.h"
61 #include "predict.h"
62 #include "basic-block.h"
63 #include "df.h"
64 #include "tm_p.h"
65 #include "debug.h"
66 #include "target.h"
67 #include "langhooks.h"
68 #include "msp430-protos.h"
69 #include "dumpfile.h"
70 #include "opts.h"
71 #include "builtins.h"
73 #include "target-def.h"
76 static void msp430_compute_frame_info (void);
80 /* Run-time Target Specification. */
82 bool msp430x = true;
84 struct GTY(()) machine_function
86 /* If set, the rest of the fields have been computed. */
87 int computed;
88 /* Which registers need to be saved in the pro/epilogue. */
89 int need_to_save [FIRST_PSEUDO_REGISTER];
91 /* These fields describe the frame layout... */
92 /* arg pointer */
93 /* 2/4 bytes for saved PC */
94 int framesize_regs;
95 /* frame pointer */
96 int framesize_locals;
97 int framesize_outgoing;
98 /* stack pointer */
99 int framesize;
101 /* How much we adjust the stack when returning from an exception
102 handler. */
103 rtx eh_stack_adjust;
106 /* This is our init_machine_status, as set in
107 msp_option_override. */
108 static struct machine_function *
109 msp430_init_machine_status (void)
111 struct machine_function *m;
113 m = ggc_cleared_alloc<machine_function> ();
115 return m;
118 #undef TARGET_OPTION_OVERRIDE
119 #define TARGET_OPTION_OVERRIDE msp430_option_override
121 static const char * msp430_mcu_names [] =
123 "msp430afe221", "msp430afe222", "msp430afe223", "msp430afe231",
124 "msp430afe232", "msp430afe233", "msp430afe251", "msp430afe252",
125 "msp430afe253", "msp430c091", "msp430c092", "msp430c111",
126 "msp430c1111", "msp430c112", "msp430c1121", "msp430c1331",
127 "msp430c1351", "msp430c311s", "msp430c312", "msp430c313",
128 "msp430c314", "msp430c315", "msp430c323", "msp430c325",
129 "msp430c336", "msp430c337", "msp430c412", "msp430c413",
130 "msp430e112", "msp430e313", "msp430e315", "msp430e325",
131 "msp430e337", "msp430f110", "msp430f1101", "msp430f1101a",
132 "msp430f1111", "msp430f1111a", "msp430f112", "msp430f1121",
133 "msp430f1121a", "msp430f1122", "msp430f1132", "msp430f122",
134 "msp430f1222", "msp430f123", "msp430f1232", "msp430f133",
135 "msp430f135", "msp430f147", "msp430f1471", "msp430f148",
136 "msp430f1481", "msp430f149", "msp430f1491", "msp430f155",
137 "msp430f156", "msp430f157", "msp430f1610", "msp430f1611",
138 "msp430f1612", "msp430f167", "msp430f168", "msp430f169",
139 "msp430f2001", "msp430f2002", "msp430f2003", "msp430f2011",
140 "msp430f2012", "msp430f2013", "msp430f2101", "msp430f2111",
141 "msp430f2112", "msp430f2121", "msp430f2122", "msp430f2131",
142 "msp430f2132", "msp430f2232", "msp430f2234", "msp430f2252",
143 "msp430f2254", "msp430f2272", "msp430f2274", "msp430f233",
144 "msp430f2330", "msp430f235", "msp430f2350", "msp430f2370",
145 "msp430f2410", "msp430f247", "msp430f2471", "msp430f248",
146 "msp430f2481", "msp430f249", "msp430f2491", "msp430f412",
147 "msp430f413", "msp430f4132", "msp430f415", "msp430f4152",
148 "msp430f417", "msp430f423", "msp430f423a", "msp430f425",
149 "msp430f4250", "msp430f425a", "msp430f4260", "msp430f427",
150 "msp430f4270", "msp430f427a", "msp430f435", "msp430f4351",
151 "msp430f436", "msp430f4361", "msp430f437", "msp430f4371",
152 "msp430f438", "msp430f439", "msp430f447", "msp430f448",
153 "msp430f4481", "msp430f449", "msp430f4491", "msp430f477",
154 "msp430f478", "msp430f4783", "msp430f4784", "msp430f479",
155 "msp430f4793", "msp430f4794", "msp430fe423", "msp430fe4232",
156 "msp430fe423a", "msp430fe4242", "msp430fe425", "msp430fe4252",
157 "msp430fe425a", "msp430fe427", "msp430fe4272", "msp430fe427a",
158 "msp430fg4250", "msp430fg4260", "msp430fg4270", "msp430fg437",
159 "msp430fg438", "msp430fg439", "msp430fg477", "msp430fg478",
160 "msp430fg479", "msp430fw423", "msp430fw425", "msp430fw427",
161 "msp430fw428", "msp430fw429", "msp430g2001", "msp430g2101",
162 "msp430g2102", "msp430g2111", "msp430g2112", "msp430g2113",
163 "msp430g2121", "msp430g2131", "msp430g2132", "msp430g2152",
164 "msp430g2153", "msp430g2201", "msp430g2202", "msp430g2203",
165 "msp430g2210", "msp430g2211", "msp430g2212", "msp430g2213",
166 "msp430g2221", "msp430g2230", "msp430g2231", "msp430g2232",
167 "msp430g2233", "msp430g2252", "msp430g2253", "msp430g2302",
168 "msp430g2303", "msp430g2312", "msp430g2313", "msp430g2332",
169 "msp430g2333", "msp430g2352", "msp430g2353", "msp430g2402",
170 "msp430g2403", "msp430g2412", "msp430g2413", "msp430g2432",
171 "msp430g2433", "msp430g2444", "msp430g2452", "msp430g2453",
172 "msp430g2513", "msp430g2533", "msp430g2544", "msp430g2553",
173 "msp430g2744", "msp430g2755", "msp430g2855", "msp430g2955",
174 "msp430i2020", "msp430i2021", "msp430i2030", "msp430i2031",
175 "msp430i2040", "msp430i2041", "msp430l092", "msp430p112",
176 "msp430p313", "msp430p315", "msp430p315s", "msp430p325",
177 "msp430p337", "msp430tch5e"
180 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
181 If a specific MCU has not been selected then return a generic symbol instead. */
183 const char *
184 msp430_mcu_name (void)
186 if (target_mcu)
188 unsigned int i;
189 static char mcu_name [64];
191 snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu);
192 for (i = strlen (mcu_name); i--;)
193 mcu_name[i] = TOUPPER (mcu_name[i]);
194 return mcu_name;
197 return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
200 static void
201 msp430_option_override (void)
203 init_machine_status = msp430_init_machine_status;
205 if (target_cpu)
207 if (strcasecmp (target_cpu, "msp430x") == 0)
208 msp430x = true;
209 else /* target_cpu == "msp430" - already handled by the front end. */
210 msp430x = false;
212 /* Note - the front end has already ensured at most
213 one of target_cpu and target_mcu will be set. */
214 else if (target_mcu)
216 int i;
218 /* If we are given an MCU name, we assume that it supports 430X.
219 Then we check to see if it is one of the known MCUs that only
220 supports 430. */
221 msp430x = true;
223 for (i = ARRAY_SIZE (msp430_mcu_names); i--;)
224 if (strcasecmp (msp430_mcu_names[i], target_mcu) == 0)
226 msp430x = false;
227 break;
229 /* It is not an error if we do not match the MCU name. There are
230 hundreds of them. */
233 if (TARGET_LARGE && !msp430x)
234 error ("-mlarge requires a 430X-compatible -mmcu=");
236 if (msp430_code_region == UPPER && ! msp430x)
237 error ("-mcode-region=upper requires 430X-compatible cpu");
238 if (msp430_data_region == UPPER && ! msp430x)
239 error ("-mdata-region=upper requires 430X-compatible cpu");
241 if (flag_exceptions || flag_non_call_exceptions
242 || flag_unwind_tables || flag_asynchronous_unwind_tables)
243 flag_omit_frame_pointer = false;
244 else
245 flag_omit_frame_pointer = true;
247 /* This is a hack to work around a problem with the newlib build
248 mechanism. Newlib always appends CFLAGS to the end of the GCC
249 command line and always sets -O2 in CFLAGS. Thus it is not
250 possible to build newlib with -Os enabled. Until now... */
251 if (TARGET_OPT_SPACE && optimize < 3)
252 optimize_size = 1;
255 #undef TARGET_SCALAR_MODE_SUPPORTED_P
256 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
258 static bool
259 msp430_scalar_mode_supported_p (machine_mode m)
261 if (m == PSImode && msp430x)
262 return true;
263 #if 0
264 if (m == TImode)
265 return true;
266 #endif
267 return default_scalar_mode_supported_p (m);
272 /* Storage Layout */
274 #undef TARGET_MS_BITFIELD_LAYOUT_P
275 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
277 bool
278 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
280 return false;
285 /* Register Usage */
287 /* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single
288 PSImode value, but not an SImode value. */
290 msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
291 machine_mode mode)
293 if (mode == PSImode && msp430x)
294 return 1;
295 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
296 / UNITS_PER_WORD);
299 /* Implements HARD_REGNO_NREGS_HAS_PADDING. */
301 msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED,
302 machine_mode mode)
304 if (mode == PSImode && msp430x)
305 return 1;
306 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
307 / UNITS_PER_WORD);
310 /* Implements HARD_REGNO_NREGS_WITH_PADDING. */
312 msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED,
313 machine_mode mode)
315 if (mode == PSImode)
316 return 2;
317 return msp430_hard_regno_nregs (regno, mode);
320 /* Implements HARD_REGNO_MODE_OK. */
322 msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED,
323 machine_mode mode)
325 return regno <= (ARG_POINTER_REGNUM - msp430_hard_regno_nregs (regno, mode));
328 /* Implements MODES_TIEABLE_P. */
329 bool
330 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2)
332 if ((mode1 == PSImode || mode2 == SImode)
333 || (mode1 == SImode || mode2 == PSImode))
334 return false;
336 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
337 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
338 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
339 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
342 #undef TARGET_FRAME_POINTER_REQUIRED
343 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
345 static bool
346 msp430_frame_pointer_required (void)
348 return false;
351 #undef TARGET_CAN_ELIMINATE
352 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
354 static bool
355 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
356 const int to_reg ATTRIBUTE_UNUSED)
358 return true;
361 /* Implements INITIAL_ELIMINATION_OFFSET. */
363 msp430_initial_elimination_offset (int from, int to)
365 int rv = 0; /* As if arg to arg. */
367 msp430_compute_frame_info ();
369 switch (to)
371 case STACK_POINTER_REGNUM:
372 rv += cfun->machine->framesize_outgoing;
373 rv += cfun->machine->framesize_locals;
374 /* Fall through. */
375 case FRAME_POINTER_REGNUM:
376 rv += cfun->machine->framesize_regs;
377 /* Allow for the saved return address. */
378 rv += (TARGET_LARGE ? 4 : 2);
379 /* NB/ No need to allow for crtl->args.pretend_args_size.
380 GCC does that for us. */
381 break;
382 default:
383 gcc_unreachable ();
386 switch (from)
388 case FRAME_POINTER_REGNUM:
389 /* Allow for the fall through above. */
390 rv -= (TARGET_LARGE ? 4 : 2);
391 rv -= cfun->machine->framesize_regs;
392 case ARG_POINTER_REGNUM:
393 break;
394 default:
395 gcc_unreachable ();
398 return rv;
401 /* Named Address Space support */
404 /* Return the appropriate mode for a named address pointer. */
405 #undef TARGET_ADDR_SPACE_POINTER_MODE
406 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
407 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
408 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
410 static machine_mode
411 msp430_addr_space_pointer_mode (addr_space_t addrspace)
413 switch (addrspace)
415 default:
416 case ADDR_SPACE_GENERIC:
417 return Pmode;
418 case ADDR_SPACE_NEAR:
419 return HImode;
420 case ADDR_SPACE_FAR:
421 return PSImode;
425 /* Function pointers are stored in unwind_word sized
426 variables, so make sure that unwind_word is big enough. */
427 #undef TARGET_UNWIND_WORD_MODE
428 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
430 static machine_mode
431 msp430_unwind_word_mode (void)
433 return TARGET_LARGE ? PSImode : HImode;
436 /* Determine if one named address space is a subset of another. */
437 #undef TARGET_ADDR_SPACE_SUBSET_P
438 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
439 static bool
440 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
442 if (subset == superset)
443 return true;
444 else
445 return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR);
448 #undef TARGET_ADDR_SPACE_CONVERT
449 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
450 /* Convert from one address space to another. */
451 static rtx
452 msp430_addr_space_convert (rtx op, tree from_type, tree to_type)
454 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
455 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
456 rtx result;
458 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
460 /* This is unpredictable, as we're truncating off usable address
461 bits. */
463 if (CONSTANT_P (op))
464 return gen_rtx_CONST (HImode, op);
466 result = gen_reg_rtx (HImode);
467 emit_insn (gen_truncpsihi2 (result, op));
468 return result;
470 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
472 /* This always works. */
474 if (CONSTANT_P (op))
475 return gen_rtx_CONST (PSImode, op);
477 result = gen_reg_rtx (PSImode);
478 emit_insn (gen_zero_extendhipsi2 (result, op));
479 return result;
481 else
482 gcc_unreachable ();
485 /* Stack Layout and Calling Conventions. */
487 /* For each function, we list the gcc version and the TI version on
488 each line, where we're converting the function names. */
489 static char const * const special_convention_function_names [] =
491 "__muldi3", "__mspabi_mpyll",
492 "__udivdi3", "__mspabi_divull",
493 "__umoddi3", "__mspabi_remull",
494 "__divdi3", "__mspabi_divlli",
495 "__moddi3", "__mspabi_remlli",
496 "__mspabi_srall",
497 "__mspabi_srlll",
498 "__mspabi_sllll",
499 "__adddf3", "__mspabi_addd",
500 "__subdf3", "__mspabi_subd",
501 "__muldf3", "__mspabi_mpyd",
502 "__divdf3", "__mspabi_divd",
503 "__mspabi_cmpd",
504 NULL
507 /* TRUE if the function passed is a "speical" function. Special
508 functions pass two DImode parameters in registers. */
509 static bool
510 msp430_special_register_convention_p (const char *name)
512 int i;
514 for (i = 0; special_convention_function_names [i]; i++)
515 if (! strcmp (name, special_convention_function_names [i]))
516 return true;
518 return false;
521 #undef TARGET_FUNCTION_VALUE_REGNO_P
522 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
524 bool
525 msp430_function_value_regno_p (unsigned int regno)
527 return regno == 12;
531 #undef TARGET_FUNCTION_VALUE
532 #define TARGET_FUNCTION_VALUE msp430_function_value
535 msp430_function_value (const_tree ret_type,
536 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
537 bool outgoing ATTRIBUTE_UNUSED)
539 return gen_rtx_REG (TYPE_MODE (ret_type), 12);
542 #undef TARGET_LIBCALL_VALUE
543 #define TARGET_LIBCALL_VALUE msp430_libcall_value
546 msp430_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
548 return gen_rtx_REG (mode, 12);
551 /* Implements INIT_CUMULATIVE_ARGS. */
552 void
553 msp430_init_cumulative_args (CUMULATIVE_ARGS *ca,
554 tree fntype ATTRIBUTE_UNUSED,
555 rtx libname ATTRIBUTE_UNUSED,
556 tree fndecl ATTRIBUTE_UNUSED,
557 int n_named_args ATTRIBUTE_UNUSED)
559 const char *fname;
560 memset (ca, 0, sizeof(*ca));
562 ca->can_split = 1;
564 if (fndecl)
565 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
566 else if (libname)
567 fname = XSTR (libname, 0);
568 else
569 fname = NULL;
571 if (fname && msp430_special_register_convention_p (fname))
572 ca->special_p = 1;
575 /* Helper function for argument passing; this function is the common
576 code that determines where an argument will be passed. */
577 static void
578 msp430_evaluate_arg (cumulative_args_t cap,
579 machine_mode mode,
580 const_tree type ATTRIBUTE_UNUSED,
581 bool named)
583 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
584 int nregs = GET_MODE_SIZE (mode);
585 int i;
587 ca->reg_count = 0;
588 ca->mem_count = 0;
590 if (!named)
591 return;
593 if (mode == PSImode)
594 nregs = 1;
595 else
596 nregs = (nregs + 1) / 2;
598 if (ca->special_p)
600 /* Function is passed two DImode operands, in R8:R11 and
601 R12:15. */
602 ca->start_reg = 8;
603 ca->reg_count = 4;
604 return;
607 switch (nregs)
609 case 1:
610 for (i = 0; i < 4; i++)
611 if (! ca->reg_used [i])
613 ca->reg_count = 1;
614 ca->start_reg = CA_FIRST_REG + i;
615 return;
617 break;
618 case 2:
619 for (i = 0; i < 3; i++)
620 if (! ca->reg_used [i] && ! ca->reg_used [i + 1])
622 ca->reg_count = 2;
623 ca->start_reg = CA_FIRST_REG + i;
624 return;
626 if (! ca->reg_used [3] && ca->can_split)
628 ca->reg_count = 1;
629 ca->mem_count = 2;
630 ca->start_reg = CA_FIRST_REG + 3;
631 return;
633 break;
634 case 3:
635 case 4:
636 ca->can_split = 0;
637 if (! ca->reg_used [0]
638 && ! ca->reg_used [1]
639 && ! ca->reg_used [2]
640 && ! ca->reg_used [3])
642 ca->reg_count = 4;
643 ca->start_reg = CA_FIRST_REG;
644 return;
646 break;
650 #undef TARGET_PROMOTE_PROTOTYPES
651 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
653 bool
654 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
656 return false;
659 #undef TARGET_FUNCTION_ARG
660 #define TARGET_FUNCTION_ARG msp430_function_arg
663 msp430_function_arg (cumulative_args_t cap,
664 machine_mode mode,
665 const_tree type,
666 bool named)
668 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
670 msp430_evaluate_arg (cap, mode, type, named);
672 if (ca->reg_count)
673 return gen_rtx_REG (mode, ca->start_reg);
675 return 0;
678 #undef TARGET_ARG_PARTIAL_BYTES
679 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
682 msp430_arg_partial_bytes (cumulative_args_t cap,
683 machine_mode mode,
684 tree type,
685 bool named)
687 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
689 msp430_evaluate_arg (cap, mode, type, named);
691 if (ca->reg_count && ca->mem_count)
692 return ca->reg_count * UNITS_PER_WORD;
694 return 0;
697 #undef TARGET_PASS_BY_REFERENCE
698 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
700 static bool
701 msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED,
702 machine_mode mode,
703 const_tree type,
704 bool named ATTRIBUTE_UNUSED)
706 return (mode == BLKmode
707 || (type && TREE_CODE (type) == RECORD_TYPE)
708 || (type && TREE_CODE (type) == UNION_TYPE));
711 #undef TARGET_CALLEE_COPIES
712 #define TARGET_CALLEE_COPIES msp430_callee_copies
714 static bool
715 msp430_callee_copies (cumulative_args_t cap ATTRIBUTE_UNUSED,
716 machine_mode mode ATTRIBUTE_UNUSED,
717 const_tree type ATTRIBUTE_UNUSED,
718 bool named ATTRIBUTE_UNUSED)
720 return true;
723 #undef TARGET_FUNCTION_ARG_ADVANCE
724 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
726 void
727 msp430_function_arg_advance (cumulative_args_t cap,
728 machine_mode mode,
729 const_tree type,
730 bool named)
732 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
733 int i;
735 msp430_evaluate_arg (cap, mode, type, named);
737 if (ca->start_reg >= CA_FIRST_REG)
738 for (i = 0; i < ca->reg_count; i ++)
739 ca->reg_used [i + ca->start_reg - CA_FIRST_REG] = 1;
741 ca->special_p = 0;
744 #undef TARGET_FUNCTION_ARG_BOUNDARY
745 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
747 static unsigned int
748 msp430_function_arg_boundary (machine_mode mode, const_tree type)
750 if (mode == BLKmode
751 && int_size_in_bytes (type) > 1)
752 return 16;
753 if (GET_MODE_BITSIZE (mode) > 8)
754 return 16;
755 return 8;
758 #undef TARGET_RETURN_IN_MEMORY
759 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
761 static bool
762 msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED)
764 machine_mode mode = TYPE_MODE (ret_type);
766 if (mode == BLKmode
767 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE)
768 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE))
769 return true;
771 if (GET_MODE_SIZE (mode) > 8)
772 return true;
774 return false;
777 #undef TARGET_GET_RAW_ARG_MODE
778 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
780 static machine_mode
781 msp430_get_raw_arg_mode (int regno)
783 return (regno == ARG_POINTER_REGNUM) ? VOIDmode : Pmode;
786 #undef TARGET_GET_RAW_RESULT_MODE
787 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
789 static machine_mode
790 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
792 return Pmode;
795 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
796 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
798 #include "gimplify.h"
799 #include "gimple-expr.h"
801 static tree
802 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
803 gimple_seq *post_p)
805 tree addr, t, type_size, rounded_size, valist_tmp;
806 unsigned HOST_WIDE_INT align, boundary;
807 bool indirect;
809 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
810 if (indirect)
811 type = build_pointer_type (type);
813 align = PARM_BOUNDARY / BITS_PER_UNIT;
814 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
816 /* When we align parameter on stack for caller, if the parameter
817 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
818 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
819 here with caller. */
820 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
821 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
823 boundary /= BITS_PER_UNIT;
825 /* Hoist the valist value into a temporary for the moment. */
826 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
828 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
829 requires greater alignment, we must perform dynamic alignment. */
830 if (boundary > align
831 && !integer_zerop (TYPE_SIZE (type)))
833 /* FIXME: This is where this function diverts from targhooks.c:
834 std_gimplify_va_arg_expr(). It works, but I do not know why... */
835 if (! POINTER_TYPE_P (type))
837 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
838 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
839 gimplify_and_add (t, pre_p);
841 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
842 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
843 valist_tmp,
844 build_int_cst (TREE_TYPE (valist), -boundary)));
845 gimplify_and_add (t, pre_p);
848 else
849 boundary = align;
851 /* If the actual alignment is less than the alignment of the type,
852 adjust the type accordingly so that we don't assume strict alignment
853 when dereferencing the pointer. */
854 boundary *= BITS_PER_UNIT;
855 if (boundary < TYPE_ALIGN (type))
857 type = build_variant_type_copy (type);
858 TYPE_ALIGN (type) = boundary;
861 /* Compute the rounded size of the type. */
862 type_size = size_in_bytes (type);
863 rounded_size = round_up (type_size, align);
865 /* Reduce rounded_size so it's sharable with the postqueue. */
866 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
868 /* Get AP. */
869 addr = valist_tmp;
871 /* Compute new value for AP. */
872 t = fold_build_pointer_plus (valist_tmp, rounded_size);
873 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
874 gimplify_and_add (t, pre_p);
876 addr = fold_convert (build_pointer_type (type), addr);
878 if (indirect)
879 addr = build_va_arg_indirect_ref (addr);
881 addr = build_va_arg_indirect_ref (addr);
883 return addr;
886 /* Addressing Modes */
888 #undef TARGET_LEGITIMATE_ADDRESS_P
889 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
891 static bool
892 reg_ok_for_addr (rtx r, bool strict)
894 int rn = REGNO (r);
896 if (strict && rn >= FIRST_PSEUDO_REGISTER)
897 rn = reg_renumber [rn];
898 if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
899 return true;
900 if (!strict)
901 return true;
902 return false;
905 bool
906 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
907 rtx x ATTRIBUTE_UNUSED,
908 bool strict ATTRIBUTE_UNUSED)
910 switch (GET_CODE (x))
912 case MEM:
913 return false;
915 case PLUS:
916 if (REG_P (XEXP (x, 0)))
918 if (GET_MODE (x) != GET_MODE (XEXP (x, 0)))
919 return false;
920 if (!reg_ok_for_addr (XEXP (x, 0), strict))
921 return false;
922 switch (GET_CODE (XEXP (x, 1)))
924 case CONST:
925 case SYMBOL_REF:
926 case CONST_INT:
927 return true;
928 default:
929 return false;
932 return false;
934 case REG:
935 if (!reg_ok_for_addr (x, strict))
936 return false;
937 /* else... */
938 case CONST:
939 case SYMBOL_REF:
940 case CONST_INT:
941 return true;
943 default:
944 return false;
948 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
949 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p
951 bool
952 msp430_addr_space_legitimate_address_p (machine_mode mode,
953 rtx x,
954 bool strict,
955 addr_space_t as ATTRIBUTE_UNUSED)
957 return msp430_legitimate_address_p (mode, x, strict);
960 #undef TARGET_ASM_INTEGER
961 #define TARGET_ASM_INTEGER msp430_asm_integer
962 static bool
963 msp430_asm_integer (rtx x, unsigned int size, int aligned_p)
965 int c = GET_CODE (x);
967 if (size == 3 && GET_MODE (x) == PSImode)
968 size = 4;
970 switch (size)
972 case 4:
973 if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT
974 || c == PLUS || c == MINUS)
976 fprintf (asm_out_file, "\t.long\t");
977 output_addr_const (asm_out_file, x);
978 fputc ('\n', asm_out_file);
979 return true;
981 break;
983 return default_assemble_integer (x, size, aligned_p);
986 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
987 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
988 static bool
989 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
991 debug_rtx(x);
992 return false;
995 #undef TARGET_LEGITIMATE_CONSTANT_P
996 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
998 static bool
999 msp430_legitimate_constant (machine_mode mode, rtx x)
1001 return ! CONST_INT_P (x)
1002 || mode != PSImode
1003 /* GCC does not know the width of the PSImode, so make
1004 sure that it does not try to use a constant value that
1005 is out of range. */
1006 || (INTVAL (x) < (1 << 20) && INTVAL (x) >= (-1 << 20));
1010 #undef TARGET_RTX_COSTS
1011 #define TARGET_RTX_COSTS msp430_rtx_costs
1013 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED,
1014 int code,
1015 int outer_code ATTRIBUTE_UNUSED,
1016 int opno ATTRIBUTE_UNUSED,
1017 int * total,
1018 bool speed ATTRIBUTE_UNUSED)
1020 switch (code)
1022 case SIGN_EXTEND:
1023 if (GET_MODE (x) == SImode && outer_code == SET)
1025 *total = COSTS_N_INSNS (4);
1026 return true;
1028 break;
1029 case ASHIFT:
1030 case ASHIFTRT:
1031 case LSHIFTRT:
1032 if (!msp430x)
1034 *total = COSTS_N_INSNS (100);
1035 return true;
1037 break;
1039 return false;
1042 /* Function Entry and Exit */
1044 /* The MSP430 call frame looks like this:
1046 <higher addresses>
1047 +--------------------+
1049 | Stack Arguments |
1051 +--------------------+ <-- "arg pointer"
1053 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1055 +--------------------+
1056 | SR if this func has|
1057 | been called via an |
1058 | interrupt. |
1059 +--------------------+ <-- SP before prologue, also AP
1061 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1063 +--------------------+ <-- "frame pointer"
1065 | Locals |
1067 +--------------------+
1069 | Outgoing Args |
1071 +--------------------+ <-- SP during function
1072 <lower addresses>
1076 /* We use this to wrap all emitted insns in the prologue, so they get
1077 the "frame-related" (/f) flag set. */
1078 static rtx
1079 F (rtx x)
1081 RTX_FRAME_RELATED_P (x) = 1;
1082 return x;
1085 /* This is the one spot that decides if a register is to be saved and
1086 restored in the prologue/epilogue. */
1087 static bool
1088 msp430_preserve_reg_p (int regno)
1090 /* PC, SP, SR, and the constant generator. */
1091 if (regno <= 3)
1092 return false;
1094 /* FIXME: add interrupt, EH, etc. */
1095 if (crtl->calls_eh_return)
1096 return true;
1098 /* Shouldn't be more than the above, but just in case... */
1099 if (fixed_regs [regno])
1100 return false;
1102 /* Interrupt handlers save all registers they use, even
1103 ones which are call saved. If they call other functions
1104 then *every* register is saved. */
1105 if (msp430_is_interrupt_func ())
1106 return ! crtl->is_leaf || df_regs_ever_live_p (regno);
1108 if (!call_used_regs [regno]
1109 && df_regs_ever_live_p (regno))
1110 return true;
1112 return false;
1115 /* Compute all the frame-related fields in our machine_function
1116 structure. */
1117 static void
1118 msp430_compute_frame_info (void)
1120 int i;
1122 cfun->machine->computed = 1;
1123 cfun->machine->framesize_regs = 0;
1124 cfun->machine->framesize_locals = get_frame_size ();
1125 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
1127 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1128 if (msp430_preserve_reg_p (i))
1130 cfun->machine->need_to_save [i] = 1;
1131 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1133 else
1134 cfun->machine->need_to_save [i] = 0;
1136 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1137 cfun->machine->framesize_locals ++;
1139 cfun->machine->framesize = (cfun->machine->framesize_regs
1140 + cfun->machine->framesize_locals
1141 + cfun->machine->framesize_outgoing);
1144 /* Attribute Handling. */
1146 const char * const ATTR_INTR = "interrupt";
1147 const char * const ATTR_WAKEUP = "wakeup";
1148 const char * const ATTR_NAKED = "naked";
1149 const char * const ATTR_REENT = "reentrant";
1150 const char * const ATTR_CRIT = "critical";
1151 const char * const ATTR_LOWER = "lower";
1152 const char * const ATTR_UPPER = "upper";
1153 const char * const ATTR_EITHER = "either";
1155 static inline bool
1156 has_attr (const char * attr, tree decl)
1158 if (decl == NULL_TREE)
1159 return false;
1160 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1163 static bool
1164 is_interrupt_func (tree decl = current_function_decl)
1166 return has_attr (ATTR_INTR, decl);
1169 /* Returns true if the current function has the "interrupt" attribute. */
1171 bool
1172 msp430_is_interrupt_func (void)
1174 return is_interrupt_func (current_function_decl);
1177 static bool
1178 is_wakeup_func (tree decl = current_function_decl)
1180 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1183 static inline bool
1184 is_naked_func (tree decl = current_function_decl)
1186 return has_attr (ATTR_NAKED, decl);
1189 static inline bool
1190 is_reentrant_func (tree decl = current_function_decl)
1192 return has_attr (ATTR_REENT, decl);
1195 static inline bool
1196 is_critical_func (tree decl = current_function_decl)
1198 return has_attr (ATTR_CRIT, decl);
1201 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1202 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args
1204 static bool
1205 msp430_allocate_stack_slots_for_args (void)
1207 /* Naked functions should not allocate stack slots for arguments. */
1208 return ! is_naked_func ();
1211 /* Verify MSP430 specific attributes. */
1212 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1214 static tree
1215 msp430_attr (tree * node,
1216 tree name,
1217 tree args,
1218 int flags ATTRIBUTE_UNUSED,
1219 bool * no_add_attrs)
1221 gcc_assert (DECL_P (* node));
1223 if (args != NULL)
1225 gcc_assert (TREE_NAME_EQ (name, ATTR_INTR));
1227 tree value = TREE_VALUE (args);
1229 switch (TREE_CODE (value))
1231 case STRING_CST:
1232 if ( strcmp (TREE_STRING_POINTER (value), "reset")
1233 && strcmp (TREE_STRING_POINTER (value), "nmi")
1234 && strcmp (TREE_STRING_POINTER (value), "watchdog"))
1235 /* Allow the attribute to be added - the linker script
1236 being used may still recognise this name. */
1237 warning (OPT_Wattributes,
1238 "unrecognised interrupt vector argument of %qE attribute",
1239 name);
1240 break;
1242 case INTEGER_CST:
1243 if (wi::gtu_p (value, 63))
1244 /* Allow the attribute to be added - the linker script
1245 being used may still recognise this value. */
1246 warning (OPT_Wattributes,
1247 "numeric argument of %qE attribute must be in range 0..63",
1248 name);
1249 break;
1251 default:
1252 warning (OPT_Wattributes,
1253 "argument of %qE attribute is not a string constant or number",
1254 name);
1255 *no_add_attrs = true;
1256 break;
1260 const char * message = NULL;
1262 if (TREE_CODE (* node) != FUNCTION_DECL)
1264 message = "%qE attribute only applies to functions";
1266 else if (TREE_NAME_EQ (name, ATTR_INTR))
1268 if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE
1269 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node))))
1270 message = "interrupt handlers must be void";
1272 else if (TREE_NAME_EQ (name, ATTR_REENT))
1274 if (is_naked_func (* node))
1275 message = "naked functions cannot be reentrant";
1276 else if (is_critical_func (* node))
1277 message = "critical functions cannot be reentrant";
1279 else if (TREE_NAME_EQ (name, ATTR_CRIT))
1281 if (is_naked_func (* node))
1282 message = "naked functions cannot be critical";
1283 else if (is_reentrant_func (* node))
1284 message = "reentranct functions cannot be critical";
1286 else if (TREE_NAME_EQ (name, ATTR_NAKED))
1288 if (is_critical_func (* node))
1289 message = "critical functions cannot be naked";
1290 else if (is_reentrant_func (* node))
1291 message = "reentrant functions cannot be naked";
1294 if (message)
1296 warning (OPT_Wattributes, message, name);
1297 * no_add_attrs = true;
1300 return NULL_TREE;
1303 static tree
1304 msp430_section_attr (tree * node,
1305 tree name,
1306 tree args,
1307 int flags ATTRIBUTE_UNUSED,
1308 bool * no_add_attrs ATTRIBUTE_UNUSED)
1310 gcc_assert (DECL_P (* node));
1311 gcc_assert (args == NULL);
1313 const char * message = NULL;
1315 if (TREE_NAME_EQ (name, ATTR_UPPER))
1317 if (has_attr (ATTR_LOWER, * node))
1318 message = "already marked with 'lower' attribute";
1319 else if (has_attr (ATTR_EITHER, * node))
1320 message = "already marked with 'either' attribute";
1321 else if (! msp430x)
1322 message = "upper attribute needs a 430X cpu";
1324 else if (TREE_NAME_EQ (name, ATTR_LOWER))
1326 if (has_attr (ATTR_UPPER, * node))
1327 message = "already marked with 'upper' attribute";
1328 else if (has_attr (ATTR_EITHER, * node))
1329 message = "already marked with 'either' attribute";
1331 else
1333 gcc_assert (TREE_NAME_EQ (name, ATTR_EITHER));
1335 if (has_attr (ATTR_LOWER, * node))
1336 message = "already marked with 'lower' attribute";
1337 else if (has_attr (ATTR_UPPER, * node))
1338 message = "already marked with 'upper' attribute";
1341 if (message)
1343 warning (OPT_Wattributes, message, name);
1344 * no_add_attrs = true;
1347 return NULL_TREE;
1350 #undef TARGET_ATTRIBUTE_TABLE
1351 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1353 /* Table of MSP430-specific attributes. */
1354 const struct attribute_spec msp430_attribute_table[] =
1356 /* Name min_num_args type_req, affects_type_identity
1357 max_num_args, fn_type_req
1358 decl_req handler. */
1359 { ATTR_INTR, 0, 1, true, false, false, msp430_attr, false },
1360 { ATTR_NAKED, 0, 0, true, false, false, msp430_attr, false },
1361 { ATTR_REENT, 0, 0, true, false, false, msp430_attr, false },
1362 { ATTR_CRIT, 0, 0, true, false, false, msp430_attr, false },
1363 { ATTR_WAKEUP, 0, 0, true, false, false, msp430_attr, false },
1365 { ATTR_LOWER, 0, 0, true, false, false, msp430_section_attr, false },
1366 { ATTR_UPPER, 0, 0, true, false, false, msp430_section_attr, false },
1367 { ATTR_EITHER, 0, 0, true, false, false, msp430_section_attr, false },
1369 { NULL, 0, 0, false, false, false, NULL, false }
1372 #undef TARGET_ASM_FUNCTION_PROLOGUE
1373 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1375 static void
1376 msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
1378 int r, n;
1380 fprintf (outfile, "; start of function\n");
1382 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
1384 fprintf (outfile, "; attributes: ");
1385 if (is_naked_func ())
1386 fprintf (outfile, "naked ");
1387 if (msp430_is_interrupt_func ())
1388 fprintf (outfile, "interrupt ");
1389 if (is_reentrant_func ())
1390 fprintf (outfile, "reentrant ");
1391 if (is_critical_func ())
1392 fprintf (outfile, "critical ");
1393 if (is_wakeup_func ())
1394 fprintf (outfile, "wakeup ");
1395 fprintf (outfile, "\n");
1398 fprintf (outfile, "; framesize_regs: %d\n", cfun->machine->framesize_regs);
1399 fprintf (outfile, "; framesize_locals: %d\n", cfun->machine->framesize_locals);
1400 fprintf (outfile, "; framesize_outgoing: %d\n", cfun->machine->framesize_outgoing);
1401 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
1402 fprintf (outfile, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM));
1403 fprintf (outfile, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM));
1405 n = 0;
1406 fprintf (outfile, "; saved regs:");
1407 for (r = 0; r < ARG_POINTER_REGNUM; r++)
1408 if (cfun->machine->need_to_save [r])
1410 fprintf (outfile, " %s", reg_names [r]);
1411 n = 1;
1413 if (n == 0)
1414 fprintf (outfile, "(none)");
1415 fprintf (outfile, "\n");
1418 /* Common code to change the stack pointer. */
1419 static void
1420 increment_stack (HOST_WIDE_INT amount)
1422 rtx inc;
1423 rtx sp = stack_pointer_rtx;
1425 if (amount == 0)
1426 return;
1428 if (amount < 0)
1430 inc = GEN_INT (- amount);
1431 if (TARGET_LARGE)
1432 F (emit_insn (gen_subpsi3 (sp, sp, inc)));
1433 else
1434 F (emit_insn (gen_subhi3 (sp, sp, inc)));
1436 else
1438 inc = GEN_INT (amount);
1439 if (TARGET_LARGE)
1440 emit_insn (gen_addpsi3 (sp, sp, inc));
1441 else
1442 emit_insn (gen_addhi3 (sp, sp, inc));
1446 void
1447 msp430_start_function (FILE *file, const char *name, tree decl)
1449 tree int_attr;
1451 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1452 if (int_attr != NULL_TREE)
1454 tree intr_vector = TREE_VALUE (int_attr);
1456 if (intr_vector != NULL_TREE)
1458 char buf[101];
1460 intr_vector = TREE_VALUE (intr_vector);
1462 /* The interrupt attribute has a vector value. Turn this into a
1463 section name, switch to that section and put the address of
1464 the current function into that vector slot. Note msp430_attr()
1465 has already verified the vector name for us. */
1466 if (TREE_CODE (intr_vector) == STRING_CST)
1467 sprintf (buf, "__interrupt_vector_%.80s",
1468 TREE_STRING_POINTER (intr_vector));
1469 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1470 sprintf (buf, "__interrupt_vector_%u",
1471 (unsigned int) TREE_INT_CST_LOW (intr_vector));
1473 switch_to_section (get_section (buf, SECTION_CODE, decl));
1474 fputs ("\t.word\t", file);
1475 assemble_name (file, name);
1476 fputc ('\n', file);
1477 fputc ('\t', file);
1481 switch_to_section (function_section (decl));
1482 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1485 static const char * const lower_prefix = ".lower";
1486 static const char * const upper_prefix = ".upper";
1487 static const char * const either_prefix = ".either";
1489 /* Generate a prefix for a section name, based upon
1490 the region into which the object should be placed. */
1492 static const char *
1493 gen_prefix (tree decl)
1495 if (DECL_ONE_ONLY (decl))
1496 return NULL;
1498 /* If the user has specified a particular section then do not use any prefix. */
1499 if (has_attr ("section", decl))
1500 return NULL;
1502 /* If the object has __attribute__((lower)) then use the ".lower." prefix. */
1503 if (has_attr (ATTR_LOWER, decl))
1504 return lower_prefix;
1506 /* If we are compiling for the MSP430 then we do not support the upper region. */
1507 if (! msp430x)
1508 return NULL;
1510 if (has_attr (ATTR_UPPER, decl))
1511 return upper_prefix;
1513 if (has_attr (ATTR_EITHER, decl))
1514 return either_prefix;
1516 if (TREE_CODE (decl) == FUNCTION_DECL)
1518 if (msp430_code_region == LOWER)
1519 return lower_prefix;
1521 if (msp430_code_region == UPPER)
1522 return upper_prefix;
1524 if (msp430_code_region == EITHER)
1525 return either_prefix;
1527 else
1529 if (msp430_data_region == LOWER)
1530 return lower_prefix;
1532 if (msp430_data_region == UPPER)
1533 return upper_prefix;
1535 if (msp430_data_region == EITHER)
1536 return either_prefix;
1539 return NULL;
1542 #undef TARGET_ASM_SELECT_SECTION
1543 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1545 static section *
1546 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
1548 gcc_assert (decl != NULL_TREE);
1550 if (TREE_CODE (decl) == STRING_CST
1551 || TREE_CODE (decl) == CONSTRUCTOR
1552 || TREE_CODE (decl) == INTEGER_CST
1553 || TREE_CODE (decl) == VECTOR_CST
1554 || TREE_CODE (decl) == COMPLEX_CST)
1555 return default_select_section (decl, reloc, align);
1557 /* In large mode we must make sure that interrupt handlers are put into
1558 low memory as the vector table only accepts 16-bit addresses. */
1559 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl))
1560 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
1562 const char * prefix = gen_prefix (decl);
1563 if (prefix == NULL)
1565 if (TREE_CODE (decl) == FUNCTION_DECL)
1566 return text_section;
1567 else
1568 return default_select_section (decl, reloc, align);
1571 const char * sec;
1572 switch (categorize_decl_for_section (decl, reloc))
1574 case SECCAT_TEXT: sec = ".text"; break;
1575 case SECCAT_DATA: sec = ".data"; break;
1576 case SECCAT_BSS: sec = ".bss"; break;
1577 case SECCAT_RODATA: sec = ".rodata"; break;
1579 case SECCAT_RODATA_MERGE_STR:
1580 case SECCAT_RODATA_MERGE_STR_INIT:
1581 case SECCAT_RODATA_MERGE_CONST:
1582 case SECCAT_SRODATA:
1583 case SECCAT_DATA_REL:
1584 case SECCAT_DATA_REL_LOCAL:
1585 case SECCAT_DATA_REL_RO:
1586 case SECCAT_DATA_REL_RO_LOCAL:
1587 case SECCAT_SDATA:
1588 case SECCAT_SBSS:
1589 case SECCAT_TDATA:
1590 case SECCAT_TBSS:
1591 return default_select_section (decl, reloc, align);
1593 default:
1594 gcc_unreachable ();
1597 const char * dec_name = DECL_SECTION_NAME (decl);
1598 char * name = ACONCAT ((prefix, sec, dec_name, NULL));
1600 return get_named_section (decl, name, 0);
1603 #undef TARGET_ASM_FUNCTION_SECTION
1604 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1606 static section *
1607 msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit)
1609 const char * name;
1611 gcc_assert (DECL_SECTION_NAME (decl) != NULL);
1612 name = DECL_SECTION_NAME (decl);
1614 const char * prefix = gen_prefix (decl);
1615 if (prefix == NULL
1616 || strncmp (name, prefix, strlen (prefix)) == 0)
1617 return default_function_section (decl, freq, startup, exit);
1619 name = ACONCAT ((prefix, name, NULL));
1620 return get_named_section (decl, name, 0);
1623 #undef TARGET_SECTION_TYPE_FLAGS
1624 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1626 unsigned int
1627 msp430_section_type_flags (tree decl, const char * name, int reloc)
1629 if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0)
1630 name += strlen (lower_prefix);
1631 else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0)
1632 name += strlen (upper_prefix);
1633 else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
1634 name += strlen (either_prefix);
1636 return default_section_type_flags (decl, name, reloc);
1639 #undef TARGET_ASM_UNIQUE_SECTION
1640 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1642 static void
1643 msp430_unique_section (tree decl, int reloc)
1645 gcc_assert (decl != NULL_TREE);
1647 /* In large mode we must make sure that interrupt handlers are put into
1648 low memory as the vector table only accepts 16-bit addresses. */
1649 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl))
1651 set_decl_section_name (decl, ".lowtext");
1652 return;
1655 default_unique_section (decl, reloc);
1657 const char * prefix;
1659 if ( TREE_CODE (decl) == STRING_CST
1660 || TREE_CODE (decl) == CONSTRUCTOR
1661 || TREE_CODE (decl) == INTEGER_CST
1662 || TREE_CODE (decl) == VECTOR_CST
1663 || TREE_CODE (decl) == COMPLEX_CST
1664 || (prefix = gen_prefix (decl)) == NULL
1666 return;
1668 const char * dec_name = DECL_SECTION_NAME (decl);
1669 char * name = ACONCAT ((prefix, dec_name, NULL));
1671 set_decl_section_name (decl, name);
1674 /* Emit a declaration of a common symbol.
1675 If a data region is in use then put the symbol into the
1676 equivalent .bss section instead. */
1678 void
1679 msp430_output_aligned_decl_common (FILE * stream,
1680 const tree decl,
1681 const char * name,
1682 unsigned HOST_WIDE_INT size,
1683 unsigned int align)
1685 if (msp430_data_region == ANY)
1687 fprintf (stream, COMMON_ASM_OP);
1688 assemble_name (stream, name);
1689 fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
1690 size, align / BITS_PER_UNIT);
1692 else
1694 section * sec;
1696 if (decl)
1697 sec = msp430_select_section (decl, 0, align);
1698 else
1699 switch (msp430_data_region)
1701 case UPPER: sec = get_named_section (NULL, ".upper.bss", 0); break;
1702 case LOWER: sec = get_named_section (NULL, ".lower.bss", 0); break;
1703 case EITHER: sec = get_named_section (NULL, ".either.bss", 0); break;
1704 default:
1705 gcc_unreachable ();
1707 gcc_assert (sec != NULL);
1709 switch_to_section (sec);
1710 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
1711 targetm.asm_out.globalize_label (stream, name);
1712 ASM_WEAKEN_LABEL (stream, name);
1713 ASM_OUTPUT_LABEL (stream, name);
1714 ASM_OUTPUT_SKIP (stream, size ? size : 1);
1718 bool
1719 msp430_do_not_relax_short_jumps (void)
1721 /* When placing code into "either" low or high memory we do not want the linker
1722 to grow the size of sections, which it can do if it is encounters a branch to
1723 a label that is too far away. So we tell the cbranch patterns to avoid using
1724 short jumps when there is a chance that the instructions will end up in a low
1725 section. */
1726 return
1727 msp430_code_region == EITHER
1728 || msp430_code_region == LOWER
1729 || has_attr (ATTR_EITHER, current_function_decl)
1730 || has_attr (ATTR_LOWER, current_function_decl);
1733 enum msp430_builtin
1735 MSP430_BUILTIN_BIC_SR,
1736 MSP430_BUILTIN_BIS_SR,
1737 MSP430_BUILTIN_DELAY_CYCLES,
1738 MSP430_BUILTIN_max
1741 static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max];
1743 static void
1744 msp430_init_builtins (void)
1746 tree void_ftype_int = build_function_type_list (void_type_node, integer_type_node, NULL);
1747 tree void_ftype_longlong = build_function_type_list (void_type_node, long_long_integer_type_node, NULL);
1749 msp430_builtins[MSP430_BUILTIN_BIC_SR] =
1750 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
1751 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
1753 msp430_builtins[MSP430_BUILTIN_BIS_SR] =
1754 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
1755 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
1757 msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
1758 add_builtin_function ( "__delay_cycles", void_ftype_longlong,
1759 MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL, NULL_TREE);
1762 static tree
1763 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
1765 switch (code)
1767 case MSP430_BUILTIN_BIC_SR:
1768 case MSP430_BUILTIN_BIS_SR:
1769 case MSP430_BUILTIN_DELAY_CYCLES:
1770 return msp430_builtins[code];
1771 default:
1772 return error_mark_node;
1776 /* These constants are really register reads, which are faster than
1777 regular constants. */
1778 static int
1779 cg_magic_constant (HOST_WIDE_INT c)
1781 switch (c)
1783 case 0xffff:
1784 case -1:
1785 case 0:
1786 case 1:
1787 case 2:
1788 case 4:
1789 case 8:
1790 return 1;
1791 default:
1792 return 0;
1796 static rtx
1797 msp430_expand_delay_cycles (rtx arg)
1799 HOST_WIDE_INT i, c, n;
1800 /* extra cycles for MSP430X instructions */
1801 #define CYCX(M,X) (msp430x ? (X) : (M))
1803 if (GET_CODE (arg) != CONST_INT)
1805 error ("__delay_cycles() only takes constant arguments");
1806 return NULL_RTX;
1809 c = INTVAL (arg);
1811 if (HOST_BITS_PER_WIDE_INT > 32)
1813 if (c < 0)
1815 error ("__delay_cycles only takes non-negative cycle counts.");
1816 return NULL_RTX;
1820 emit_insn (gen_delay_cycles_start (arg));
1822 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
1823 if (c > 3 * 0xffff + CYCX (7, 10))
1825 n = c;
1826 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long (x<=0xffff) loop */
1827 if (c >= 0x10000 * 7 + CYCX (14, 16))
1829 i = 0x10000;
1830 c -= CYCX (14, 16) + 7 * 0x10000;
1831 i += c / 4;
1832 c %= 4;
1833 if ((unsigned long long) i > 0xffffffffULL)
1835 error ("__delay_cycles is limited to 32-bit loop counts.");
1836 return NULL_RTX;
1839 else
1841 i = (c - CYCX (14, 16)) / 7;
1842 c -= CYCX (14, 16) + i * 7;
1845 if (cg_magic_constant (i & 0xffff))
1846 c ++;
1847 if (cg_magic_constant ((i >> 16) & 0xffff))
1848 c ++;
1850 if (msp430x)
1851 emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c)));
1852 else
1853 emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
1856 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */
1857 if (c > 12)
1859 n = c;
1860 i = (c - CYCX (7, 10)) / 3;
1861 c -= CYCX (7, 10) + i * 3;
1863 if (cg_magic_constant (i))
1864 c ++;
1866 if (msp430x)
1867 emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c)));
1868 else
1869 emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c)));
1872 while (c > 1)
1874 emit_insn (gen_delay_cycles_2 ());
1875 c -= 2;
1878 if (c)
1880 emit_insn (gen_delay_cycles_1 ());
1881 c -= 1;
1884 emit_insn (gen_delay_cycles_end (arg));
1886 return NULL_RTX;
1889 static rtx
1890 msp430_expand_builtin (tree exp,
1891 rtx target ATTRIBUTE_UNUSED,
1892 rtx subtarget ATTRIBUTE_UNUSED,
1893 machine_mode mode ATTRIBUTE_UNUSED,
1894 int ignore ATTRIBUTE_UNUSED)
1896 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
1897 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
1898 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1900 if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
1901 return msp430_expand_delay_cycles (arg1);
1903 if (! msp430_is_interrupt_func ())
1905 error ("MSP430 builtin functions only work inside interrupt handlers");
1906 return NULL_RTX;
1909 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
1910 arg1 = force_reg (mode, arg1);
1912 switch (fcode)
1914 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break;
1915 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break;
1916 default:
1917 internal_error ("bad builtin code");
1918 break;
1920 return NULL_RTX;
1923 #undef TARGET_INIT_BUILTINS
1924 #define TARGET_INIT_BUILTINS msp430_init_builtins
1926 #undef TARGET_EXPAND_BUILTIN
1927 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
1929 #undef TARGET_BUILTIN_DECL
1930 #define TARGET_BUILTIN_DECL msp430_builtin_decl
1932 void
1933 msp430_expand_prologue (void)
1935 int i, j;
1936 int fs;
1937 /* Always use stack_pointer_rtx instead of calling
1938 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
1939 that there is a single rtx representing the stack pointer,
1940 namely stack_pointer_rtx, and uses == to recognize it. */
1941 rtx sp = stack_pointer_rtx;
1942 rtx p;
1944 if (is_naked_func ())
1946 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
1947 examines the output of the gen_prologue() function. */
1948 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
1949 return;
1952 emit_insn (gen_prologue_start_marker ());
1954 if (is_critical_func ())
1956 emit_insn (gen_push_intr_state ());
1957 emit_insn (gen_disable_interrupts ());
1959 else if (is_reentrant_func ())
1960 emit_insn (gen_disable_interrupts ());
1962 if (!cfun->machine->computed)
1963 msp430_compute_frame_info ();
1965 if (flag_stack_usage_info)
1966 current_function_static_stack_size = cfun->machine->framesize;
1968 if (crtl->args.pretend_args_size)
1970 rtx note;
1972 gcc_assert (crtl->args.pretend_args_size == 2);
1974 p = emit_insn (gen_grow_and_swap ());
1976 /* Document the stack decrement... */
1977 note = F (gen_rtx_SET (stack_pointer_rtx,
1978 gen_rtx_MINUS (Pmode, stack_pointer_rtx, GEN_INT (2))));
1979 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
1981 /* ...and the establishment of a new location for the return address. */
1982 note = F (gen_rtx_SET (gen_rtx_MEM (Pmode,
1983 gen_rtx_PLUS (Pmode,
1984 stack_pointer_rtx,
1985 GEN_INT (-2))),
1986 pc_rtx));
1987 add_reg_note (p, REG_CFA_OFFSET, note);
1988 F (p);
1991 for (i = 15; i >= 4; i--)
1992 if (cfun->machine->need_to_save [i])
1994 int seq, count;
1995 rtx note;
1997 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
1999 count = i - seq;
2001 if (msp430x)
2003 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */
2004 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
2005 GEN_INT (count))));
2007 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2009 XVECEXP (note, 0, 0)
2010 = F (gen_rtx_SET (stack_pointer_rtx,
2011 gen_rtx_PLUS (Pmode,
2012 stack_pointer_rtx,
2013 GEN_INT (count * (TARGET_LARGE ? -4 : -2)))));
2015 /* *sp-- = R[i-j] */
2016 /* sp+N R10
2018 sp R4 */
2019 for (j = 0; j < count; j ++)
2021 rtx addr;
2022 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2024 if (ofs)
2025 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2026 else
2027 addr = stack_pointer_rtx;
2029 XVECEXP (note, 0, j + 1) =
2030 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2031 gen_rtx_REG (Pmode, i - j)) );
2034 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2035 i -= count - 1;
2037 else
2038 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2041 if (frame_pointer_needed)
2042 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2044 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2046 increment_stack (- fs);
2048 emit_insn (gen_prologue_end_marker ());
2051 void
2052 msp430_expand_epilogue (int is_eh)
2054 int i;
2055 int fs;
2056 int helper_n = 0;
2058 if (is_naked_func ())
2060 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2061 examines the output of the gen_epilogue() function. */
2062 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2063 return;
2066 if (cfun->machine->need_to_save [10])
2068 /* Check for a helper function. */
2069 helper_n = 7; /* For when the loop below never sees a match. */
2070 for (i = 9; i >= 4; i--)
2071 if (!cfun->machine->need_to_save [i])
2073 helper_n = 10 - i;
2074 for (; i >= 4; i--)
2075 if (cfun->machine->need_to_save [i])
2077 helper_n = 0;
2078 break;
2080 break;
2084 emit_insn (gen_epilogue_start_marker ());
2086 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), "main") == 0)
2087 emit_insn (gen_msp430_refsym_need_exit ());
2089 if (is_wakeup_func ())
2090 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2091 status register current residing on the stack. When this function
2092 executes its RETI instruction the SR will be updated with this saved
2093 value, thus ensuring that the processor is woken up from any low power
2094 state in which it may be residing. */
2095 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2097 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2099 increment_stack (fs);
2101 if (is_eh)
2103 /* We need to add the right "SP" register save just after the
2104 regular ones, so that when we pop it off we're in the EH
2105 return frame, not this one. This overwrites our own return
2106 address, but we're not going to be returning anyway. */
2107 rtx r12 = gen_rtx_REG (Pmode, 12);
2108 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
2110 /* R12 will hold the new SP. */
2111 i = cfun->machine->framesize_regs;
2112 emit_move_insn (r12, stack_pointer_rtx);
2113 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
2114 emit_insn (addPmode (r12, r12, GEN_INT (i)));
2115 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, i)), r12);
2118 for (i = 4; i <= 15; i++)
2119 if (cfun->machine->need_to_save [i])
2121 int seq, count;
2123 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
2125 count = seq - i;
2127 if (msp430x)
2129 /* Note: With TARGET_LARGE we still use
2130 POPM as POPX.A is two bytes bigger. */
2131 emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
2132 GEN_INT (count)));
2133 i += count - 1;
2135 else if (i == 11 - helper_n
2136 && ! msp430_is_interrupt_func ()
2137 && ! is_reentrant_func ()
2138 && ! is_critical_func ()
2139 && crtl->args.pretend_args_size == 0
2140 /* Calling the helper takes as many bytes as the POP;RET sequence. */
2141 && helper_n > 1
2142 && !is_eh)
2144 emit_insn (gen_epilogue_helper (GEN_INT (helper_n)));
2145 return;
2147 else
2148 emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
2151 if (is_eh)
2153 /* Also pop SP, which puts us into the EH return frame. Except
2154 that you can't "pop" sp, you have to just load it off the
2155 stack. */
2156 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode, stack_pointer_rtx));
2159 if (crtl->args.pretend_args_size)
2160 emit_insn (gen_swap_and_shrink ());
2162 if (is_critical_func ())
2163 emit_insn (gen_pop_intr_state ());
2164 else if (is_reentrant_func ())
2165 emit_insn (gen_enable_interrupts ());
2167 emit_jump_insn (gen_msp_return ());
2170 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2171 m32c_emit_eh_epilogue. */
2173 msp430_eh_return_stackadj_rtx (void)
2175 if (!cfun->machine->eh_stack_adjust)
2177 rtx sa;
2179 sa = gen_rtx_REG (Pmode, 15);
2180 cfun->machine->eh_stack_adjust = sa;
2182 return cfun->machine->eh_stack_adjust;
2185 /* This function is called before reload, to "fix" the stack in
2186 preparation for an EH return. */
2187 void
2188 msp430_expand_eh_return (rtx eh_handler)
2190 /* These are all Pmode */
2191 rtx ap, sa, ra, tmp;
2193 ap = arg_pointer_rtx;
2194 sa = msp430_eh_return_stackadj_rtx ();
2195 ra = eh_handler;
2197 tmp = ap;
2198 tmp = gen_rtx_PLUS (Pmode, ap, sa);
2199 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
2200 tmp = gen_rtx_MEM (Pmode, tmp);
2201 emit_move_insn (tmp, ra);
2204 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
2205 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2206 void
2207 msp430_init_dwarf_reg_sizes_extra (tree address)
2209 int i;
2210 rtx addr = expand_normal (address);
2211 rtx mem = gen_rtx_MEM (BLKmode, addr);
2213 if (!msp430x)
2214 return;
2216 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2218 unsigned int dnum = DWARF_FRAME_REGNUM (i);
2219 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
2221 if (rnum < DWARF_FRAME_REGISTERS)
2223 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
2225 emit_move_insn (adjust_address (mem, QImode, offset),
2226 gen_int_mode (4, QImode));
2231 /* This is a list of MD patterns that implement fixed-count shifts. */
2232 static struct
2234 const char *name;
2235 int count;
2236 int need_430x;
2237 rtx (*genfunc)(rtx,rtx);
2239 const_shift_helpers[] =
2241 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2243 CSH ("slli", 1, 1, slli_1),
2244 CSH ("slll", 1, 1, slll_1),
2245 CSH ("slll", 2, 1, slll_2),
2247 CSH ("srai", 1, 0, srai_1),
2248 CSH ("sral", 1, 0, sral_1),
2249 CSH ("sral", 2, 0, sral_2),
2251 CSH ("srll", 1, 0, srll_1),
2252 CSH ("srll", 2, 1, srll_2x),
2253 { 0, 0, 0, 0 }
2254 #undef CSH
2257 /* The MSP430 ABI defines a number of helper functions that should be
2258 used for, for example, 32-bit shifts. This function is called to
2259 emit such a function, using the table above to optimize some
2260 cases. */
2261 void
2262 msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants)
2264 rtx c, f;
2265 char *helper_const = NULL;
2266 int arg2 = 13;
2267 int arg1sz = 1;
2268 machine_mode arg0mode = GET_MODE (operands[0]);
2269 machine_mode arg1mode = GET_MODE (operands[1]);
2270 machine_mode arg2mode = GET_MODE (operands[2]);
2271 int have_430x = msp430x ? 1 : 0;
2273 if (CONST_INT_P (operands[2]))
2275 int i;
2277 for (i=0; const_shift_helpers[i].name; i++)
2279 if (const_shift_helpers[i].need_430x <= have_430x
2280 && strcmp (helper_name, const_shift_helpers[i].name) == 0
2281 && INTVAL (operands[2]) == const_shift_helpers[i].count)
2283 emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1]));
2284 return;
2289 if (arg1mode == VOIDmode)
2290 arg1mode = arg0mode;
2291 if (arg2mode == VOIDmode)
2292 arg2mode = arg0mode;
2294 if (arg1mode == SImode)
2296 arg2 = 14;
2297 arg1sz = 2;
2300 if (const_variants
2301 && CONST_INT_P (operands[2])
2302 && INTVAL (operands[2]) >= 1
2303 && INTVAL (operands[2]) <= 15)
2305 /* Note that the INTVAL is limited in value and length by the conditional above. */
2306 int len = strlen (helper_name) + 4;
2307 helper_const = (char *) xmalloc (len);
2308 snprintf (helper_const, len, "%s_%d", helper_name, (int) INTVAL (operands[2]));
2311 emit_move_insn (gen_rtx_REG (arg1mode, 12),
2312 operands[1]);
2313 if (!helper_const)
2314 emit_move_insn (gen_rtx_REG (arg2mode, arg2),
2315 operands[2]);
2317 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12),
2318 gen_rtx_SYMBOL_REF (VOIDmode, helper_const ? helper_const : helper_name),
2319 GEN_INT (0));
2320 c = emit_call_insn (c);
2321 RTL_CONST_CALL_P (c) = 1;
2323 f = 0;
2324 use_regs (&f, 12, arg1sz);
2325 if (!helper_const)
2326 use_regs (&f, arg2, 1);
2327 add_function_usage_to (c, f);
2329 emit_move_insn (operands[0],
2330 gen_rtx_REG (arg0mode, 12));
2333 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
2334 void
2335 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
2337 /* constants we're looking for, not constants which are allowed. */
2338 int const_op_idx = 1;
2340 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
2341 const_op_idx = 2;
2343 if (GET_CODE (operands[const_op_idx]) != REG
2344 && GET_CODE (operands[const_op_idx]) != MEM)
2345 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
2348 /* Simplify_gen_subreg() doesn't handle memory references the way we
2349 need it to below, so we use this function for when we must get a
2350 valid subreg in a "natural" state. */
2352 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
2354 rtx rv;
2356 if (GET_CODE (r) == SUBREG
2357 && SUBREG_BYTE (r) == 0)
2359 rtx ireg = SUBREG_REG (r);
2360 machine_mode imode = GET_MODE (ireg);
2362 /* special case for (HI (SI (PSI ...), 0)) */
2363 if (imode == PSImode
2364 && mode == HImode
2365 && byte == 0)
2366 rv = gen_rtx_SUBREG (mode, ireg, byte);
2367 else
2368 rv = simplify_gen_subreg (mode, ireg, imode, byte);
2370 else if (GET_CODE (r) == MEM)
2371 rv = adjust_address (r, mode, byte);
2372 else if (GET_CODE (r) == SYMBOL_REF
2373 && (byte == 0 || byte == 2)
2374 && mode == HImode)
2376 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
2377 rv = gen_rtx_CONST (HImode, r);
2379 else
2380 rv = simplify_gen_subreg (mode, r, omode, byte);
2382 if (!rv)
2383 gcc_unreachable ();
2385 return rv;
2388 /* Called by movsi_x to generate the HImode operands. */
2389 void
2390 msp430_split_movsi (rtx *operands)
2392 rtx op00, op02, op10, op12;
2394 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
2395 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
2397 if (GET_CODE (operands[1]) == CONST
2398 || GET_CODE (operands[1]) == SYMBOL_REF)
2400 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
2401 op10 = gen_rtx_CONST (HImode, op10);
2402 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
2403 op12 = gen_rtx_CONST (HImode, op12);
2405 else
2407 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
2408 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
2411 if (rtx_equal_p (operands[0], operands[1]))
2413 operands[2] = op02;
2414 operands[4] = op12;
2415 operands[3] = op00;
2416 operands[5] = op10;
2418 else if (rtx_equal_p (op00, op12)
2419 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
2420 || (REG_P (op00) && reg_mentioned_p (op00, op10))
2421 /* Or storing (rN) into mem (rN). */
2422 || (REG_P (op10) && reg_mentioned_p (op10, op00))
2425 operands[2] = op02;
2426 operands[4] = op12;
2427 operands[3] = op00;
2428 operands[5] = op10;
2430 else
2432 operands[2] = op00;
2433 operands[4] = op10;
2434 operands[3] = op02;
2435 operands[5] = op12;
2440 /* The MSPABI specifies the names of various helper functions, many of
2441 which are compatible with GCC's helpers. This table maps the GCC
2442 name to the MSPABI name. */
2443 static const struct
2445 char const * const gcc_name;
2446 char const * const ti_name;
2448 helper_function_name_mappings [] =
2450 /* Floating point to/from integer conversions. */
2451 { "__truncdfsf2", "__mspabi_cvtdf" },
2452 { "__extendsfdf2", "__mspabi_cvtfd" },
2453 { "__fixdfhi", "__mspabi_fixdi" },
2454 { "__fixdfsi", "__mspabi_fixdli" },
2455 { "__fixdfdi", "__mspabi_fixdlli" },
2456 { "__fixunsdfhi", "__mspabi_fixdu" },
2457 { "__fixunsdfsi", "__mspabi_fixdul" },
2458 { "__fixunsdfdi", "__mspabi_fixdull" },
2459 { "__fixsfhi", "__mspabi_fixfi" },
2460 { "__fixsfsi", "__mspabi_fixfli" },
2461 { "__fixsfdi", "__mspabi_fixflli" },
2462 { "__fixunsfhi", "__mspabi_fixfu" },
2463 { "__fixunsfsi", "__mspabi_fixful" },
2464 { "__fixunsfdi", "__mspabi_fixfull" },
2465 { "__floathisf", "__mspabi_fltif" },
2466 { "__floatsisf", "__mspabi_fltlif" },
2467 { "__floatdisf", "__mspabi_fltllif" },
2468 { "__floathidf", "__mspabi_fltid" },
2469 { "__floatsidf", "__mspabi_fltlid" },
2470 { "__floatdidf", "__mspabi_fltllid" },
2471 { "__floatunhisf", "__mspabi_fltuf" },
2472 { "__floatunsisf", "__mspabi_fltulf" },
2473 { "__floatundisf", "__mspabi_fltullf" },
2474 { "__floatunhidf", "__mspabi_fltud" },
2475 { "__floatunsidf", "__mspabi_fltuld" },
2476 { "__floatundidf", "__mspabi_fltulld" },
2478 /* Floating point comparisons. */
2479 /* GCC uses individual functions for each comparison, TI uses one
2480 compare <=> function. */
2482 /* Floating point arithmatic */
2483 { "__adddf3", "__mspabi_addd" },
2484 { "__addsf3", "__mspabi_addf" },
2485 { "__divdf3", "__mspabi_divd" },
2486 { "__divsf3", "__mspabi_divf" },
2487 { "__muldf3", "__mspabi_mpyd" },
2488 { "__mulsf3", "__mspabi_mpyf" },
2489 { "__subdf3", "__mspabi_subd" },
2490 { "__subsf3", "__mspabi_subf" },
2491 /* GCC does not use helper functions for negation */
2493 /* Integer multiply, divide, remainder. */
2494 { "__mulhi3", "__mspabi_mpyi" },
2495 { "__mulsi3", "__mspabi_mpyl" },
2496 { "__muldi3", "__mspabi_mpyll" },
2497 #if 0
2498 /* Clarify signed vs unsigned first. */
2499 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */
2500 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */
2501 #endif
2503 { "__divhi3", "__mspabi_divi" },
2504 { "__divsi3", "__mspabi_divli" },
2505 { "__divdi3", "__mspabi_divlli" },
2506 { "__udivhi3", "__mspabi_divu" },
2507 { "__udivsi3", "__mspabi_divlu" },
2508 { "__udivdi3", "__mspabi_divllu" },
2509 { "__modhi3", "__mspabi_remi" },
2510 { "__modsi3", "__mspabi_remli" },
2511 { "__moddi3", "__mspabi_remlli" },
2512 { "__umodhi3", "__mspabi_remu" },
2513 { "__umodsi3", "__mspabi_remul" },
2514 { "__umoddi3", "__mspabi_remull" },
2516 /* Bitwise operations. */
2517 /* Rotation - no rotation support yet. */
2518 /* Logical left shift - gcc already does these itself. */
2519 /* Arithmetic left shift - gcc already does these itself. */
2520 /* Arithmetic right shift - gcc already does these itself. */
2522 { NULL, NULL }
2525 /* Returns true if the current MCU supports an F5xxx series
2526 hardware multiper. */
2528 bool
2529 msp430_use_f5_series_hwmult (void)
2531 static const char * cached_match = NULL;
2532 static bool cached_result;
2534 if (msp430_hwmult_type == F5SERIES)
2535 return true;
2537 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2538 return false;
2540 if (target_mcu == cached_match)
2541 return cached_result;
2543 cached_match = target_mcu;
2545 if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
2546 return cached_result = true;
2547 if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
2548 return cached_result = true;
2549 if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
2550 return cached_result = true;
2552 static const char * known_f5_mult_mcus [] =
2554 "cc430f5123", "cc430f5125", "cc430f5133",
2555 "cc430f5135", "cc430f5137", "cc430f5143",
2556 "cc430f5145", "cc430f5147", "cc430f6125",
2557 "cc430f6126", "cc430f6127", "cc430f6135",
2558 "cc430f6137", "cc430f6143", "cc430f6145",
2559 "cc430f6147", "msp430bt5190", "msp430sl5438a",
2560 "msp430xgeneric"
2562 int i;
2564 for (i = ARRAY_SIZE (known_f5_mult_mcus); i--;)
2565 if (strcasecmp (target_mcu, known_f5_mult_mcus[i]) == 0)
2566 return cached_result = true;
2568 return cached_result = false;
2571 /* Returns true if the current MCU has a second generation
2572 32-bit hardware multiplier. */
2574 static bool
2575 use_32bit_hwmult (void)
2577 static const char * known_32bit_mult_mcus [] =
2579 "msp430f4783", "msp430f4793", "msp430f4784",
2580 "msp430f4794", "msp430f47126", "msp430f47127",
2581 "msp430f47163", "msp430f47173", "msp430f47183",
2582 "msp430f47193", "msp430f47166", "msp430f47176",
2583 "msp430f47186", "msp430f47196", "msp430f47167",
2584 "msp430f47177", "msp430f47187", "msp430f47197"
2586 static const char * cached_match = NULL;
2587 static bool cached_result;
2588 int i;
2590 if (msp430_hwmult_type == LARGE)
2591 return true;
2593 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2594 return false;
2596 if (target_mcu == cached_match)
2597 return cached_result;
2599 cached_match = target_mcu;
2600 for (i = ARRAY_SIZE (known_32bit_mult_mcus); i--;)
2601 if (strcasecmp (target_mcu, known_32bit_mult_mcus[i]) == 0)
2602 return cached_result = true;
2604 return cached_result = false;
2607 /* Returns true if the current MCU does not have a
2608 hardware multiplier of any kind. */
2610 static bool
2611 msp430_no_hwmult (void)
2613 static const char * known_nomult_mcus [] =
2615 "msp430c091", "msp430c092", "msp430c111",
2616 "msp430c1111", "msp430c112", "msp430c1121",
2617 "msp430c1331", "msp430c1351", "msp430c311s",
2618 "msp430c312", "msp430c313", "msp430c314",
2619 "msp430c315", "msp430c323", "msp430c325",
2620 "msp430c412", "msp430c413", "msp430e112",
2621 "msp430e313", "msp430e315", "msp430e325",
2622 "msp430f110", "msp430f1101", "msp430f1101a",
2623 "msp430f1111", "msp430f1111a", "msp430f112",
2624 "msp430f1121", "msp430f1121a", "msp430f1122",
2625 "msp430f1132", "msp430f122", "msp430f1222",
2626 "msp430f123", "msp430f1232", "msp430f133",
2627 "msp430f135", "msp430f155", "msp430f156",
2628 "msp430f157", "msp430f2001", "msp430f2002",
2629 "msp430f2003", "msp430f2011", "msp430f2012",
2630 "msp430f2013", "msp430f2101", "msp430f2111",
2631 "msp430f2112", "msp430f2121", "msp430f2122",
2632 "msp430f2131", "msp430f2132", "msp430f2232",
2633 "msp430f2234", "msp430f2252", "msp430f2254",
2634 "msp430f2272", "msp430f2274", "msp430f412",
2635 "msp430f413", "msp430f4132", "msp430f415",
2636 "msp430f4152", "msp430f417", "msp430f4250",
2637 "msp430f4260", "msp430f4270", "msp430f435",
2638 "msp430f4351", "msp430f436", "msp430f4361",
2639 "msp430f437", "msp430f4371", "msp430f438",
2640 "msp430f439", "msp430f477", "msp430f478",
2641 "msp430f479", "msp430fe423", "msp430fe4232",
2642 "msp430fe423a", "msp430fe4242", "msp430fe425",
2643 "msp430fe4252", "msp430fe425a", "msp430fe427",
2644 "msp430fe4272", "msp430fe427a", "msp430fg4250",
2645 "msp430fg4260", "msp430fg4270", "msp430fg437",
2646 "msp430fg438", "msp430fg439", "msp430fg477",
2647 "msp430fg478", "msp430fg479", "msp430fr2032",
2648 "msp430fr2033", "msp430fr4131", "msp430fr4132",
2649 "msp430fr4133", "msp430fw423", "msp430fw425",
2650 "msp430fw427", "msp430fw428", "msp430fw429",
2651 "msp430g2001", "msp430g2101", "msp430g2102",
2652 "msp430g2111", "msp430g2112", "msp430g2113",
2653 "msp430g2121", "msp430g2131", "msp430g2132",
2654 "msp430g2152", "msp430g2153", "msp430g2201",
2655 "msp430g2202", "msp430g2203", "msp430g2210",
2656 "msp430g2211", "msp430g2212", "msp430g2213",
2657 "msp430g2221", "msp430g2230", "msp430g2231",
2658 "msp430g2232", "msp430g2233", "msp430g2252",
2659 "msp430g2253", "msp430g2302", "msp430g2303",
2660 "msp430g2312", "msp430g2313", "msp430g2332",
2661 "msp430g2333", "msp430g2352", "msp430g2353",
2662 "msp430g2402", "msp430g2403", "msp430g2412",
2663 "msp430g2413", "msp430g2432", "msp430g2433",
2664 "msp430g2444", "msp430g2452", "msp430g2453",
2665 "msp430g2513", "msp430g2533", "msp430g2544",
2666 "msp430g2553", "msp430g2744", "msp430g2755",
2667 "msp430g2855", "msp430g2955", "msp430l092",
2668 "msp430p112", "msp430p313", "msp430p315",
2669 "msp430p315s", "msp430p325", "msp430tch5e"
2671 static const char * cached_match = NULL;
2672 static bool cached_result;
2673 int i;
2675 if (msp430_hwmult_type == NONE)
2676 return true;
2678 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2679 return false;
2681 if (target_mcu == cached_match)
2682 return cached_result;
2684 cached_match = target_mcu;
2685 for (i = ARRAY_SIZE (known_nomult_mcus); i--;)
2686 if (strcasecmp (target_mcu, known_nomult_mcus[i]) == 0)
2687 return cached_result = true;
2689 return cached_result = false;
2692 /* This function does the same as the default, but it will replace GCC
2693 function names with the MSPABI-specified ones. */
2695 void
2696 msp430_output_labelref (FILE *file, const char *name)
2698 int i;
2700 for (i = 0; helper_function_name_mappings [i].gcc_name; i++)
2701 if (strcmp (helper_function_name_mappings [i].gcc_name, name) == 0)
2703 name = helper_function_name_mappings [i].ti_name;
2704 break;
2707 /* If we have been given a specific MCU name then we may be
2708 able to make use of its hardware multiply capabilities. */
2709 if (msp430_hwmult_type != NONE)
2711 if (strcmp ("__mspabi_mpyi", name) == 0)
2713 if (msp430_use_f5_series_hwmult ())
2714 name = "__mulhi2_f5";
2715 else if (! msp430_no_hwmult ())
2716 name = "__mulhi2";
2718 else if (strcmp ("__mspabi_mpyl", name) == 0)
2720 if (msp430_use_f5_series_hwmult ())
2721 name = "__mulsi2_f5";
2722 else if (use_32bit_hwmult ())
2723 name = "__mulsi2_hw32";
2724 else if (! msp430_no_hwmult ())
2725 name = "__mulsi2";
2729 fputs (name, file);
2732 /* Common code for msp430_print_operand... */
2734 static void
2735 msp430_print_operand_raw (FILE * file, rtx op)
2737 HOST_WIDE_INT i;
2739 switch (GET_CODE (op))
2741 case REG:
2742 fprintf (file, "%s", reg_names [REGNO (op)]);
2743 break;
2745 case CONST_INT:
2746 i = INTVAL (op);
2747 if (TARGET_ASM_HEX)
2748 fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
2749 else
2750 fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
2751 break;
2753 case CONST:
2754 case PLUS:
2755 case MINUS:
2756 case SYMBOL_REF:
2757 case LABEL_REF:
2758 output_addr_const (file, op);
2759 break;
2761 default:
2762 print_rtl (file, op);
2763 break;
2767 #undef TARGET_PRINT_OPERAND_ADDRESS
2768 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
2770 /* Output to stdio stream FILE the assembler syntax for an
2771 instruction operand that is a memory reference whose address
2772 is ADDR. */
2774 static void
2775 msp430_print_operand_addr (FILE * file, rtx addr)
2777 switch (GET_CODE (addr))
2779 case PLUS:
2780 msp430_print_operand_raw (file, XEXP (addr, 1));
2781 gcc_assert (REG_P (XEXP (addr, 0)));
2782 fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]);
2783 return;
2785 case REG:
2786 fprintf (file, "@");
2787 break;
2789 case CONST:
2790 case CONST_INT:
2791 case SYMBOL_REF:
2792 case LABEL_REF:
2793 fprintf (file, "&");
2794 break;
2796 default:
2797 break;
2800 msp430_print_operand_raw (file, addr);
2803 #undef TARGET_PRINT_OPERAND
2804 #define TARGET_PRINT_OPERAND msp430_print_operand
2806 /* A low 16-bits of int/lower of register pair
2807 B high 16-bits of int/higher of register pair
2808 C bits 32-47 of a 64-bit value/reg 3 of a DImode value
2809 D bits 48-63 of a 64-bit value/reg 4 of a DImode value
2810 H like %B (for backwards compatibility)
2811 I inverse of value
2812 J an integer without a # prefix
2813 L like %A (for backwards compatibility)
2814 O offset of the top of the stack
2815 Q like X but generates an A postfix
2816 R inverse of condition code, unsigned.
2817 X X instruction postfix in large mode
2818 Y value - 4
2819 Z value - 1
2820 b .B or .W or .A, depending upon the mode
2821 p bit position
2822 r inverse of condition code
2823 x like X but only for pointers. */
2825 static void
2826 msp430_print_operand (FILE * file, rtx op, int letter)
2828 rtx addr;
2830 /* We can't use c, n, a, or l. */
2831 switch (letter)
2833 case 'Z':
2834 gcc_assert (CONST_INT_P (op));
2835 /* Print the constant value, less one. */
2836 fprintf (file, "#%ld", INTVAL (op) - 1);
2837 return;
2838 case 'Y':
2839 gcc_assert (CONST_INT_P (op));
2840 /* Print the constant value, less four. */
2841 fprintf (file, "#%ld", INTVAL (op) - 4);
2842 return;
2843 case 'I':
2844 if (GET_CODE (op) == CONST_INT)
2846 /* Inverse of constants */
2847 int i = INTVAL (op);
2848 fprintf (file, "%d", ~i);
2849 return;
2851 op = XEXP (op, 0);
2852 break;
2853 case 'r': /* Conditional jump where the condition is reversed. */
2854 switch (GET_CODE (op))
2856 case EQ: fprintf (file, "NE"); break;
2857 case NE: fprintf (file, "EQ"); break;
2858 case GEU: fprintf (file, "LO"); break;
2859 case LTU: fprintf (file, "HS"); break;
2860 case GE: fprintf (file, "L"); break;
2861 case LT: fprintf (file, "GE"); break;
2862 /* Assume these have reversed operands. */
2863 case GTU: fprintf (file, "HS"); break;
2864 case LEU: fprintf (file, "LO"); break;
2865 case GT: fprintf (file, "GE"); break;
2866 case LE: fprintf (file, "L"); break;
2867 default:
2868 msp430_print_operand_raw (file, op);
2869 break;
2871 return;
2872 case 'R': /* Conditional jump where the operands are reversed. */
2873 switch (GET_CODE (op))
2875 case GTU: fprintf (file, "LO"); break;
2876 case LEU: fprintf (file, "HS"); break;
2877 case GT: fprintf (file, "L"); break;
2878 case LE: fprintf (file, "GE"); break;
2879 default:
2880 msp430_print_operand_raw (file, op);
2881 break;
2883 return;
2884 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
2885 gcc_assert (CONST_INT_P (op));
2886 fprintf (file, "#%d", 1 << INTVAL (op));
2887 return;
2888 case 'b':
2889 switch (GET_MODE (op))
2891 case QImode: fprintf (file, ".B"); return;
2892 case HImode: fprintf (file, ".W"); return;
2893 case PSImode: fprintf (file, ".A"); return;
2894 case SImode: fprintf (file, ".A"); return;
2895 default:
2896 return;
2898 case 'A':
2899 case 'L': /* Low half. */
2900 switch (GET_CODE (op))
2902 case MEM:
2903 op = adjust_address (op, Pmode, 0);
2904 break;
2905 case REG:
2906 break;
2907 case CONST_INT:
2908 op = GEN_INT (INTVAL (op) & 0xffff);
2909 letter = 0;
2910 break;
2911 default:
2912 /* If you get here, figure out a test case :-) */
2913 gcc_unreachable ();
2915 break;
2916 case 'B':
2917 case 'H': /* high half */
2918 switch (GET_CODE (op))
2920 case MEM:
2921 op = adjust_address (op, Pmode, 2);
2922 break;
2923 case REG:
2924 op = gen_rtx_REG (Pmode, REGNO (op) + 1);
2925 break;
2926 case CONST_INT:
2927 op = GEN_INT (INTVAL (op) >> 16);
2928 letter = 0;
2929 break;
2930 default:
2931 /* If you get here, figure out a test case :-) */
2932 gcc_unreachable ();
2934 break;
2935 case 'C':
2936 switch (GET_CODE (op))
2938 case MEM:
2939 op = adjust_address (op, Pmode, 3);
2940 break;
2941 case REG:
2942 op = gen_rtx_REG (Pmode, REGNO (op) + 2);
2943 break;
2944 case CONST_INT:
2945 op = GEN_INT ((long long) INTVAL (op) >> 32);
2946 letter = 0;
2947 break;
2948 default:
2949 /* If you get here, figure out a test case :-) */
2950 gcc_unreachable ();
2952 break;
2953 case 'D':
2954 switch (GET_CODE (op))
2956 case MEM:
2957 op = adjust_address (op, Pmode, 4);
2958 break;
2959 case REG:
2960 op = gen_rtx_REG (Pmode, REGNO (op) + 3);
2961 break;
2962 case CONST_INT:
2963 op = GEN_INT ((long long) INTVAL (op) >> 48);
2964 letter = 0;
2965 break;
2966 default:
2967 /* If you get here, figure out a test case :-) */
2968 gcc_unreachable ();
2970 break;
2972 case 'X':
2973 /* This is used to turn, for example, an ADD opcode into an ADDX
2974 opcode when we're using 20-bit addresses. */
2975 if (TARGET_LARGE || GET_MODE (op) == PSImode)
2976 fprintf (file, "X");
2977 /* We don't care which operand we use, but we want 'X' in the MD
2978 file, so we do it this way. */
2979 return;
2981 case 'x':
2982 /* Similarly, but only for PSImodes. BIC, for example, needs this. */
2983 if (GET_MODE (op) == PSImode)
2984 fprintf (file, "X");
2985 return;
2987 case 'Q':
2988 /* Likewise, for BR -> BRA. */
2989 if (TARGET_LARGE)
2990 fprintf (file, "A");
2991 return;
2993 case 'O':
2994 /* Computes the offset to the top of the stack for the current frame.
2995 This has to be done here rather than in, say, msp430_expand_builtin()
2996 because builtins are expanded before the frame layout is determined. */
2997 fprintf (file, "%d",
2998 msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM)
2999 - (TARGET_LARGE ? 4 : 2));
3000 return;
3002 case 'J':
3003 gcc_assert (GET_CODE (op) == CONST_INT);
3004 case 0:
3005 break;
3006 default:
3007 output_operand_lossage ("invalid operand prefix");
3008 return;
3011 switch (GET_CODE (op))
3013 case REG:
3014 msp430_print_operand_raw (file, op);
3015 break;
3017 case MEM:
3018 addr = XEXP (op, 0);
3019 msp430_print_operand_addr (file, addr);
3020 break;
3022 case CONST:
3023 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
3025 op = XEXP (op, 0);
3026 switch (INTVAL (XEXP (op, 2)))
3028 case 0:
3029 fprintf (file, "#lo (");
3030 msp430_print_operand_raw (file, XEXP (op, 0));
3031 fprintf (file, ")");
3032 break;
3034 case 16:
3035 fprintf (file, "#hi (");
3036 msp430_print_operand_raw (file, XEXP (op, 0));
3037 fprintf (file, ")");
3038 break;
3040 default:
3041 output_operand_lossage ("invalid zero extract");
3042 break;
3044 break;
3046 /* Fall through. */
3047 case CONST_INT:
3048 case SYMBOL_REF:
3049 case LABEL_REF:
3050 if (letter == 0)
3051 fprintf (file, "#");
3052 msp430_print_operand_raw (file, op);
3053 break;
3055 case EQ: fprintf (file, "EQ"); break;
3056 case NE: fprintf (file, "NE"); break;
3057 case GEU: fprintf (file, "HS"); break;
3058 case LTU: fprintf (file, "LO"); break;
3059 case GE: fprintf (file, "GE"); break;
3060 case LT: fprintf (file, "L"); break;
3062 default:
3063 print_rtl (file, op);
3064 break;
3069 /* Frame stuff. */
3072 msp430_return_addr_rtx (int count)
3074 int ra_size;
3075 if (count)
3076 return NULL_RTX;
3078 ra_size = TARGET_LARGE ? 4 : 2;
3079 if (crtl->args.pretend_args_size)
3080 ra_size += 2;
3082 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size)));
3086 msp430_incoming_return_addr_rtx (void)
3088 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
3091 /* Instruction generation stuff. */
3093 /* Generate a sequence of instructions to sign-extend an HI
3094 value into an SI value. Handles the tricky case where
3095 we are overwriting the destination. */
3097 const char *
3098 msp430x_extendhisi (rtx * operands)
3100 if (REGNO (operands[0]) == REGNO (operands[1]))
3101 /* Low word of dest == source word. */
3102 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */
3104 if (! msp430x)
3105 /* Note: This sequence is approximately the same length as invoking a helper
3106 function to perform the sign-extension, as in:
3108 MOV.W %1, %L0
3109 MOV.W %1, r12
3110 CALL __mspabi_srai_15
3111 MOV.W r12, %H0
3113 but this version does not involve any function calls or using argument
3114 registers, so it reduces register pressure. */
3115 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */
3117 if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
3118 /* High word of dest == source word. */
3119 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
3121 /* No overlap between dest and source. */
3122 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */
3125 /* Likewise for logical right shifts. */
3126 const char *
3127 msp430x_logical_shift_right (rtx amount)
3129 /* The MSP430X's logical right shift instruction - RRUM - does
3130 not use an extension word, so we cannot encode a repeat count.
3131 Try various alternatives to work around this. If the count
3132 is in a register we are stuck, hence the assert. */
3133 gcc_assert (CONST_INT_P (amount));
3135 if (INTVAL (amount) <= 0
3136 || INTVAL (amount) >= 16)
3137 return "# nop logical shift.";
3139 if (INTVAL (amount) > 0
3140 && INTVAL (amount) < 5)
3141 return "rrum.w\t%2, %0"; /* Two bytes. */
3143 if (INTVAL (amount) > 4
3144 && INTVAL (amount) < 9)
3145 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
3147 /* First we logically shift right by one. Now we know
3148 that the top bit is zero and we can use the arithmetic
3149 right shift instruction to perform the rest of the shift. */
3150 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */
3153 struct gcc_target targetm = TARGET_INITIALIZER;
3155 #include "gt-msp430.h"