]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/msp430/msp430.c
2015-06-08 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / config / msp430 / msp430.c
1 /* Subroutines used for code generation on TI MSP430 processors.
2 Copyright (C) 2012-2015 Free Software Foundation, Inc.
3 Contributed by Red Hat.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "input.h"
26 #include "alias.h"
27 #include "symtab.h"
28 #include "tree.h"
29 #include "fold-const.h"
30 #include "stor-layout.h"
31 #include "calls.h"
32 #include "rtl.h"
33 #include "regs.h"
34 #include "hard-reg-set.h"
35 #include "insn-config.h"
36 #include "conditions.h"
37 #include "output.h"
38 #include "insn-attr.h"
39 #include "flags.h"
40 #include "function.h"
41 #include "expmed.h"
42 #include "dojump.h"
43 #include "explow.h"
44 #include "emit-rtl.h"
45 #include "varasm.h"
46 #include "stmt.h"
47 #include "expr.h"
48 #include "insn-codes.h"
49 #include "optabs.h"
50 #include "libfuncs.h"
51 #include "recog.h"
52 #include "diagnostic-core.h"
53 #include "toplev.h"
54 #include "reload.h"
55 #include "dominance.h"
56 #include "cfg.h"
57 #include "cfgrtl.h"
58 #include "cfganal.h"
59 #include "lcm.h"
60 #include "cfgbuild.h"
61 #include "cfgcleanup.h"
62 #include "predict.h"
63 #include "basic-block.h"
64 #include "df.h"
65 #include "tm_p.h"
66 #include "debug.h"
67 #include "target.h"
68 #include "target-def.h"
69 #include "langhooks.h"
70 #include "msp430-protos.h"
71 #include "dumpfile.h"
72 #include "opts.h"
73 #include "builtins.h"
74 \f
75
76 static void msp430_compute_frame_info (void);
77
78 \f
79
80 /* Run-time Target Specification. */
81
82 bool msp430x = true;
83
84 struct GTY(()) machine_function
85 {
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];
90
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;
100
101 /* How much we adjust the stack when returning from an exception
102 handler. */
103 rtx eh_stack_adjust;
104 };
105
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)
110 {
111 struct machine_function *m;
112
113 m = ggc_cleared_alloc<machine_function> ();
114
115 return m;
116 }
117
118 #undef TARGET_OPTION_OVERRIDE
119 #define TARGET_OPTION_OVERRIDE msp430_option_override
120
121 static const char * msp430_mcu_names [] =
122 {
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"
178 };
179
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. */
182
183 const char *
184 msp430_mcu_name (void)
185 {
186 if (target_mcu)
187 {
188 unsigned int i;
189 static char mcu_name [64];
190
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;
195 }
196
197 return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
198 }
199
200 static void
201 msp430_option_override (void)
202 {
203 init_machine_status = msp430_init_machine_status;
204
205 if (target_cpu)
206 {
207 if (strcasecmp (target_cpu, "msp430x") == 0)
208 msp430x = true;
209 else /* target_cpu == "msp430" - already handled by the front end. */
210 msp430x = false;
211 }
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)
215 {
216 int i;
217
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;
222
223 for (i = ARRAY_SIZE (msp430_mcu_names); i--;)
224 if (strcasecmp (msp430_mcu_names[i], target_mcu) == 0)
225 {
226 msp430x = false;
227 break;
228 }
229 /* It is not an error if we do not match the MCU name. There are
230 hundreds of them. */
231 }
232
233 if (TARGET_LARGE && !msp430x)
234 error ("-mlarge requires a 430X-compatible -mmcu=");
235
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");
240
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;
246
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;
253 }
254
255 #undef TARGET_SCALAR_MODE_SUPPORTED_P
256 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
257
258 static bool
259 msp430_scalar_mode_supported_p (machine_mode m)
260 {
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);
268 }
269
270 \f
271
272 /* Storage Layout */
273
274 #undef TARGET_MS_BITFIELD_LAYOUT_P
275 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
276
277 bool
278 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
279 {
280 return false;
281 }
282
283 \f
284
285 /* Register Usage */
286
287 /* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single
288 PSImode value, but not an SImode value. */
289 int
290 msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED,
291 machine_mode mode)
292 {
293 if (mode == PSImode && msp430x)
294 return 1;
295 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
296 / UNITS_PER_WORD);
297 }
298
299 /* Implements HARD_REGNO_NREGS_HAS_PADDING. */
300 int
301 msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED,
302 machine_mode mode)
303 {
304 if (mode == PSImode && msp430x)
305 return 1;
306 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
307 / UNITS_PER_WORD);
308 }
309
310 /* Implements HARD_REGNO_NREGS_WITH_PADDING. */
311 int
312 msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED,
313 machine_mode mode)
314 {
315 if (mode == PSImode)
316 return 2;
317 return msp430_hard_regno_nregs (regno, mode);
318 }
319
320 /* Implements HARD_REGNO_MODE_OK. */
321 int
322 msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED,
323 machine_mode mode)
324 {
325 return regno <= (ARG_POINTER_REGNUM - msp430_hard_regno_nregs (regno, mode));
326 }
327
328 /* Implements MODES_TIEABLE_P. */
329 bool
330 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2)
331 {
332 if ((mode1 == PSImode || mode2 == SImode)
333 || (mode1 == SImode || mode2 == PSImode))
334 return false;
335
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));
340 }
341
342 #undef TARGET_FRAME_POINTER_REQUIRED
343 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
344
345 static bool
346 msp430_frame_pointer_required (void)
347 {
348 return false;
349 }
350
351 #undef TARGET_CAN_ELIMINATE
352 #define TARGET_CAN_ELIMINATE msp430_can_eliminate
353
354 static bool
355 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
356 const int to_reg ATTRIBUTE_UNUSED)
357 {
358 return true;
359 }
360
361 /* Implements INITIAL_ELIMINATION_OFFSET. */
362 int
363 msp430_initial_elimination_offset (int from, int to)
364 {
365 int rv = 0; /* As if arg to arg. */
366
367 msp430_compute_frame_info ();
368
369 switch (to)
370 {
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 ();
384 }
385
386 switch (from)
387 {
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 ();
396 }
397
398 return rv;
399 }
400 \f
401 /* Named Address Space support */
402
403
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
409
410 static machine_mode
411 msp430_addr_space_pointer_mode (addr_space_t addrspace)
412 {
413 switch (addrspace)
414 {
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;
422 }
423 }
424
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
429
430 static machine_mode
431 msp430_unwind_word_mode (void)
432 {
433 return TARGET_LARGE ? PSImode : HImode;
434 }
435
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)
441 {
442 if (subset == superset)
443 return true;
444 else
445 return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR);
446 }
447
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)
453 {
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;
457
458 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
459 {
460 /* This is unpredictable, as we're truncating off usable address
461 bits. */
462
463 if (CONSTANT_P (op))
464 return gen_rtx_CONST (HImode, op);
465
466 result = gen_reg_rtx (HImode);
467 emit_insn (gen_truncpsihi2 (result, op));
468 return result;
469 }
470 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
471 {
472 /* This always works. */
473
474 if (CONSTANT_P (op))
475 return gen_rtx_CONST (PSImode, op);
476
477 result = gen_reg_rtx (PSImode);
478 emit_insn (gen_zero_extendhipsi2 (result, op));
479 return result;
480 }
481 else
482 gcc_unreachable ();
483 }
484 \f
485 /* Stack Layout and Calling Conventions. */
486
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 [] =
490 {
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
505 };
506
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)
511 {
512 int i;
513
514 for (i = 0; special_convention_function_names [i]; i++)
515 if (! strcmp (name, special_convention_function_names [i]))
516 return true;
517
518 return false;
519 }
520
521 #undef TARGET_FUNCTION_VALUE_REGNO_P
522 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
523
524 bool
525 msp430_function_value_regno_p (unsigned int regno)
526 {
527 return regno == 12;
528 }
529
530
531 #undef TARGET_FUNCTION_VALUE
532 #define TARGET_FUNCTION_VALUE msp430_function_value
533
534 rtx
535 msp430_function_value (const_tree ret_type,
536 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
537 bool outgoing ATTRIBUTE_UNUSED)
538 {
539 return gen_rtx_REG (TYPE_MODE (ret_type), 12);
540 }
541
542 #undef TARGET_LIBCALL_VALUE
543 #define TARGET_LIBCALL_VALUE msp430_libcall_value
544
545 rtx
546 msp430_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
547 {
548 return gen_rtx_REG (mode, 12);
549 }
550
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)
558 {
559 const char *fname;
560 memset (ca, 0, sizeof(*ca));
561
562 ca->can_split = 1;
563
564 if (fndecl)
565 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
566 else if (libname)
567 fname = XSTR (libname, 0);
568 else
569 fname = NULL;
570
571 if (fname && msp430_special_register_convention_p (fname))
572 ca->special_p = 1;
573 }
574
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)
582 {
583 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
584 int nregs = GET_MODE_SIZE (mode);
585 int i;
586
587 ca->reg_count = 0;
588 ca->mem_count = 0;
589
590 if (!named)
591 return;
592
593 if (mode == PSImode)
594 nregs = 1;
595 else
596 nregs = (nregs + 1) / 2;
597
598 if (ca->special_p)
599 {
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;
605 }
606
607 switch (nregs)
608 {
609 case 1:
610 for (i = 0; i < 4; i++)
611 if (! ca->reg_used [i])
612 {
613 ca->reg_count = 1;
614 ca->start_reg = CA_FIRST_REG + i;
615 return;
616 }
617 break;
618 case 2:
619 for (i = 0; i < 3; i++)
620 if (! ca->reg_used [i] && ! ca->reg_used [i + 1])
621 {
622 ca->reg_count = 2;
623 ca->start_reg = CA_FIRST_REG + i;
624 return;
625 }
626 if (! ca->reg_used [3] && ca->can_split)
627 {
628 ca->reg_count = 1;
629 ca->mem_count = 2;
630 ca->start_reg = CA_FIRST_REG + 3;
631 return;
632 }
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])
641 {
642 ca->reg_count = 4;
643 ca->start_reg = CA_FIRST_REG;
644 return;
645 }
646 break;
647 }
648 }
649
650 #undef TARGET_PROMOTE_PROTOTYPES
651 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
652
653 bool
654 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
655 {
656 return false;
657 }
658
659 #undef TARGET_FUNCTION_ARG
660 #define TARGET_FUNCTION_ARG msp430_function_arg
661
662 rtx
663 msp430_function_arg (cumulative_args_t cap,
664 machine_mode mode,
665 const_tree type,
666 bool named)
667 {
668 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
669
670 msp430_evaluate_arg (cap, mode, type, named);
671
672 if (ca->reg_count)
673 return gen_rtx_REG (mode, ca->start_reg);
674
675 return 0;
676 }
677
678 #undef TARGET_ARG_PARTIAL_BYTES
679 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
680
681 int
682 msp430_arg_partial_bytes (cumulative_args_t cap,
683 machine_mode mode,
684 tree type,
685 bool named)
686 {
687 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
688
689 msp430_evaluate_arg (cap, mode, type, named);
690
691 if (ca->reg_count && ca->mem_count)
692 return ca->reg_count * UNITS_PER_WORD;
693
694 return 0;
695 }
696
697 #undef TARGET_PASS_BY_REFERENCE
698 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
699
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)
705 {
706 return (mode == BLKmode
707 || (type && TREE_CODE (type) == RECORD_TYPE)
708 || (type && TREE_CODE (type) == UNION_TYPE));
709 }
710
711 #undef TARGET_CALLEE_COPIES
712 #define TARGET_CALLEE_COPIES msp430_callee_copies
713
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)
719 {
720 return true;
721 }
722
723 #undef TARGET_FUNCTION_ARG_ADVANCE
724 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
725
726 void
727 msp430_function_arg_advance (cumulative_args_t cap,
728 machine_mode mode,
729 const_tree type,
730 bool named)
731 {
732 CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
733 int i;
734
735 msp430_evaluate_arg (cap, mode, type, named);
736
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;
740
741 ca->special_p = 0;
742 }
743
744 #undef TARGET_FUNCTION_ARG_BOUNDARY
745 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
746
747 static unsigned int
748 msp430_function_arg_boundary (machine_mode mode, const_tree type)
749 {
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;
756 }
757
758 #undef TARGET_RETURN_IN_MEMORY
759 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
760
761 static bool
762 msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED)
763 {
764 machine_mode mode = TYPE_MODE (ret_type);
765
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;
770
771 if (GET_MODE_SIZE (mode) > 8)
772 return true;
773
774 return false;
775 }
776
777 #undef TARGET_GET_RAW_ARG_MODE
778 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
779
780 static machine_mode
781 msp430_get_raw_arg_mode (int regno)
782 {
783 return (regno == ARG_POINTER_REGNUM) ? VOIDmode : Pmode;
784 }
785
786 #undef TARGET_GET_RAW_RESULT_MODE
787 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
788
789 static machine_mode
790 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
791 {
792 return Pmode;
793 }
794
795 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
796 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
797
798 #include "gimplify.h"
799 #include "gimple-expr.h"
800
801 static tree
802 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
803 gimple_seq *post_p)
804 {
805 tree addr, t, type_size, rounded_size, valist_tmp;
806 unsigned HOST_WIDE_INT align, boundary;
807 bool indirect;
808
809 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
810 if (indirect)
811 type = build_pointer_type (type);
812
813 align = PARM_BOUNDARY / BITS_PER_UNIT;
814 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
815
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;
822
823 boundary /= BITS_PER_UNIT;
824
825 /* Hoist the valist value into a temporary for the moment. */
826 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
827
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)))
832 {
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))
836 {
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);
840
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);
846 }
847 }
848 else
849 boundary = align;
850
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))
856 {
857 type = build_variant_type_copy (type);
858 TYPE_ALIGN (type) = boundary;
859 }
860
861 /* Compute the rounded size of the type. */
862 type_size = size_in_bytes (type);
863 rounded_size = round_up (type_size, align);
864
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);
867
868 /* Get AP. */
869 addr = valist_tmp;
870
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);
875
876 addr = fold_convert (build_pointer_type (type), addr);
877
878 if (indirect)
879 addr = build_va_arg_indirect_ref (addr);
880
881 addr = build_va_arg_indirect_ref (addr);
882
883 return addr;
884 }
885 \f
886 /* Addressing Modes */
887
888 #undef TARGET_LEGITIMATE_ADDRESS_P
889 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
890
891 static bool
892 reg_ok_for_addr (rtx r, bool strict)
893 {
894 int rn = REGNO (r);
895
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;
903 }
904
905 bool
906 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
907 rtx x ATTRIBUTE_UNUSED,
908 bool strict ATTRIBUTE_UNUSED)
909 {
910 switch (GET_CODE (x))
911 {
912 case MEM:
913 return false;
914
915 case PLUS:
916 if (REG_P (XEXP (x, 0)))
917 {
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)))
923 {
924 case CONST:
925 case SYMBOL_REF:
926 case CONST_INT:
927 return true;
928 default:
929 return false;
930 }
931 }
932 return false;
933
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;
942
943 default:
944 return false;
945 }
946 }
947
948 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
949 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p
950
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)
956 {
957 return msp430_legitimate_address_p (mode, x, strict);
958 }
959
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)
964 {
965 int c = GET_CODE (x);
966
967 if (size == 3 && GET_MODE (x) == PSImode)
968 size = 4;
969
970 switch (size)
971 {
972 case 4:
973 if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT
974 || c == PLUS || c == MINUS)
975 {
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;
980 }
981 break;
982 }
983 return default_assemble_integer (x, size, aligned_p);
984 }
985
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)
990 {
991 debug_rtx(x);
992 return false;
993 }
994
995 #undef TARGET_LEGITIMATE_CONSTANT_P
996 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
997
998 static bool
999 msp430_legitimate_constant (machine_mode mode, rtx x)
1000 {
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));
1007 }
1008
1009 \f
1010 #undef TARGET_RTX_COSTS
1011 #define TARGET_RTX_COSTS msp430_rtx_costs
1012
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)
1019 {
1020 switch (code)
1021 {
1022 case SIGN_EXTEND:
1023 if (GET_MODE (x) == SImode && outer_code == SET)
1024 {
1025 *total = COSTS_N_INSNS (4);
1026 return true;
1027 }
1028 break;
1029 case ASHIFT:
1030 case ASHIFTRT:
1031 case LSHIFTRT:
1032 if (!msp430x)
1033 {
1034 *total = COSTS_N_INSNS (100);
1035 return true;
1036 }
1037 break;
1038 }
1039 return false;
1040 }
1041 \f
1042 /* Function Entry and Exit */
1043
1044 /* The MSP430 call frame looks like this:
1045
1046 <higher addresses>
1047 +--------------------+
1048 | |
1049 | Stack Arguments |
1050 | |
1051 +--------------------+ <-- "arg pointer"
1052 | |
1053 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1054 | |
1055 +--------------------+
1056 | SR if this func has|
1057 | been called via an |
1058 | interrupt. |
1059 +--------------------+ <-- SP before prologue, also AP
1060 | |
1061 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1062 | |
1063 +--------------------+ <-- "frame pointer"
1064 | |
1065 | Locals |
1066 | |
1067 +--------------------+
1068 | |
1069 | Outgoing Args |
1070 | |
1071 +--------------------+ <-- SP during function
1072 <lower addresses>
1073
1074 */
1075
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)
1080 {
1081 RTX_FRAME_RELATED_P (x) = 1;
1082 return x;
1083 }
1084
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)
1089 {
1090 /* PC, SP, SR, and the constant generator. */
1091 if (regno <= 3)
1092 return false;
1093
1094 /* FIXME: add interrupt, EH, etc. */
1095 if (crtl->calls_eh_return)
1096 return true;
1097
1098 /* Shouldn't be more than the above, but just in case... */
1099 if (fixed_regs [regno])
1100 return false;
1101
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);
1107
1108 if (!call_used_regs [regno]
1109 && df_regs_ever_live_p (regno))
1110 return true;
1111
1112 return false;
1113 }
1114
1115 /* Compute all the frame-related fields in our machine_function
1116 structure. */
1117 static void
1118 msp430_compute_frame_info (void)
1119 {
1120 int i;
1121
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;
1126
1127 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1128 if (msp430_preserve_reg_p (i))
1129 {
1130 cfun->machine->need_to_save [i] = 1;
1131 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1132 }
1133 else
1134 cfun->machine->need_to_save [i] = 0;
1135
1136 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1137 cfun->machine->framesize_locals ++;
1138
1139 cfun->machine->framesize = (cfun->machine->framesize_regs
1140 + cfun->machine->framesize_locals
1141 + cfun->machine->framesize_outgoing);
1142 }
1143
1144 /* Attribute Handling. */
1145
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";
1154
1155 static inline bool
1156 has_attr (const char * attr, tree decl)
1157 {
1158 if (decl == NULL_TREE)
1159 return false;
1160 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1161 }
1162
1163 static bool
1164 is_interrupt_func (tree decl = current_function_decl)
1165 {
1166 return has_attr (ATTR_INTR, decl);
1167 }
1168
1169 /* Returns true if the current function has the "interrupt" attribute. */
1170
1171 bool
1172 msp430_is_interrupt_func (void)
1173 {
1174 return is_interrupt_func (current_function_decl);
1175 }
1176
1177 static bool
1178 is_wakeup_func (tree decl = current_function_decl)
1179 {
1180 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1181 }
1182
1183 static inline bool
1184 is_naked_func (tree decl = current_function_decl)
1185 {
1186 return has_attr (ATTR_NAKED, decl);
1187 }
1188
1189 static inline bool
1190 is_reentrant_func (tree decl = current_function_decl)
1191 {
1192 return has_attr (ATTR_REENT, decl);
1193 }
1194
1195 static inline bool
1196 is_critical_func (tree decl = current_function_decl)
1197 {
1198 return has_attr (ATTR_CRIT, decl);
1199 }
1200
1201 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1202 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args
1203
1204 static bool
1205 msp430_allocate_stack_slots_for_args (void)
1206 {
1207 /* Naked functions should not allocate stack slots for arguments. */
1208 return ! is_naked_func ();
1209 }
1210
1211 /* Verify MSP430 specific attributes. */
1212 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1213
1214 static tree
1215 msp430_attr (tree * node,
1216 tree name,
1217 tree args,
1218 int flags ATTRIBUTE_UNUSED,
1219 bool * no_add_attrs)
1220 {
1221 gcc_assert (DECL_P (* node));
1222
1223 if (args != NULL)
1224 {
1225 gcc_assert (TREE_NAME_EQ (name, ATTR_INTR));
1226
1227 tree value = TREE_VALUE (args);
1228
1229 switch (TREE_CODE (value))
1230 {
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;
1241
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;
1250
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;
1257 }
1258 }
1259
1260 const char * message = NULL;
1261
1262 if (TREE_CODE (* node) != FUNCTION_DECL)
1263 {
1264 message = "%qE attribute only applies to functions";
1265 }
1266 else if (TREE_NAME_EQ (name, ATTR_INTR))
1267 {
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";
1271 }
1272 else if (TREE_NAME_EQ (name, ATTR_REENT))
1273 {
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";
1278 }
1279 else if (TREE_NAME_EQ (name, ATTR_CRIT))
1280 {
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";
1285 }
1286 else if (TREE_NAME_EQ (name, ATTR_NAKED))
1287 {
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";
1292 }
1293
1294 if (message)
1295 {
1296 warning (OPT_Wattributes, message, name);
1297 * no_add_attrs = true;
1298 }
1299
1300 return NULL_TREE;
1301 }
1302
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)
1309 {
1310 gcc_assert (DECL_P (* node));
1311 gcc_assert (args == NULL);
1312
1313 const char * message = NULL;
1314
1315 if (TREE_NAME_EQ (name, ATTR_UPPER))
1316 {
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";
1323 }
1324 else if (TREE_NAME_EQ (name, ATTR_LOWER))
1325 {
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";
1330 }
1331 else
1332 {
1333 gcc_assert (TREE_NAME_EQ (name, ATTR_EITHER));
1334
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";
1339 }
1340
1341 if (message)
1342 {
1343 warning (OPT_Wattributes, message, name);
1344 * no_add_attrs = true;
1345 }
1346
1347 return NULL_TREE;
1348 }
1349
1350 #undef TARGET_ATTRIBUTE_TABLE
1351 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1352
1353 /* Table of MSP430-specific attributes. */
1354 const struct attribute_spec msp430_attribute_table[] =
1355 {
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 },
1364
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 },
1368
1369 { NULL, 0, 0, false, false, false, NULL, false }
1370 };
1371
1372 #undef TARGET_ASM_FUNCTION_PROLOGUE
1373 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1374
1375 static void
1376 msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
1377 {
1378 int r, n;
1379
1380 fprintf (outfile, "; start of function\n");
1381
1382 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
1383 {
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");
1396 }
1397
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));
1404
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])
1409 {
1410 fprintf (outfile, " %s", reg_names [r]);
1411 n = 1;
1412 }
1413 if (n == 0)
1414 fprintf (outfile, "(none)");
1415 fprintf (outfile, "\n");
1416 }
1417
1418 /* Common code to change the stack pointer. */
1419 static void
1420 increment_stack (HOST_WIDE_INT amount)
1421 {
1422 rtx inc;
1423 rtx sp = stack_pointer_rtx;
1424
1425 if (amount == 0)
1426 return;
1427
1428 if (amount < 0)
1429 {
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)));
1435 }
1436 else
1437 {
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));
1443 }
1444 }
1445
1446 void
1447 msp430_start_function (FILE *file, const char *name, tree decl)
1448 {
1449 tree int_attr;
1450
1451 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1452 if (int_attr != NULL_TREE)
1453 {
1454 tree intr_vector = TREE_VALUE (int_attr);
1455
1456 if (intr_vector != NULL_TREE)
1457 {
1458 char buf[101];
1459
1460 intr_vector = TREE_VALUE (intr_vector);
1461
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));
1472
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);
1478 }
1479 }
1480
1481 switch_to_section (function_section (decl));
1482 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1483 }
1484
1485 static const char * const lower_prefix = ".lower";
1486 static const char * const upper_prefix = ".upper";
1487 static const char * const either_prefix = ".either";
1488
1489 /* Generate a prefix for a section name, based upon
1490 the region into which the object should be placed. */
1491
1492 static const char *
1493 gen_prefix (tree decl)
1494 {
1495 if (DECL_ONE_ONLY (decl))
1496 return NULL;
1497
1498 /* If the user has specified a particular section then do not use any prefix. */
1499 if (has_attr ("section", decl))
1500 return NULL;
1501
1502 /* If the object has __attribute__((lower)) then use the ".lower." prefix. */
1503 if (has_attr (ATTR_LOWER, decl))
1504 return lower_prefix;
1505
1506 /* If we are compiling for the MSP430 then we do not support the upper region. */
1507 if (! msp430x)
1508 return NULL;
1509
1510 if (has_attr (ATTR_UPPER, decl))
1511 return upper_prefix;
1512
1513 if (has_attr (ATTR_EITHER, decl))
1514 return either_prefix;
1515
1516 if (TREE_CODE (decl) == FUNCTION_DECL)
1517 {
1518 if (msp430_code_region == LOWER)
1519 return lower_prefix;
1520
1521 if (msp430_code_region == UPPER)
1522 return upper_prefix;
1523
1524 if (msp430_code_region == EITHER)
1525 return either_prefix;
1526 }
1527 else
1528 {
1529 if (msp430_data_region == LOWER)
1530 return lower_prefix;
1531
1532 if (msp430_data_region == UPPER)
1533 return upper_prefix;
1534
1535 if (msp430_data_region == EITHER)
1536 return either_prefix;
1537 }
1538
1539 return NULL;
1540 }
1541
1542 #undef TARGET_ASM_SELECT_SECTION
1543 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1544
1545 static section *
1546 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
1547 {
1548 gcc_assert (decl != NULL_TREE);
1549
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);
1556
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);
1561
1562 const char * prefix = gen_prefix (decl);
1563 if (prefix == NULL)
1564 {
1565 if (TREE_CODE (decl) == FUNCTION_DECL)
1566 return text_section;
1567 else
1568 return default_select_section (decl, reloc, align);
1569 }
1570
1571 const char * sec;
1572 switch (categorize_decl_for_section (decl, reloc))
1573 {
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;
1578
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);
1592
1593 default:
1594 gcc_unreachable ();
1595 }
1596
1597 const char * dec_name = DECL_SECTION_NAME (decl);
1598 char * name = ACONCAT ((prefix, sec, dec_name, NULL));
1599
1600 return get_named_section (decl, name, 0);
1601 }
1602
1603 #undef TARGET_ASM_FUNCTION_SECTION
1604 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1605
1606 static section *
1607 msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit)
1608 {
1609 const char * name;
1610
1611 gcc_assert (DECL_SECTION_NAME (decl) != NULL);
1612 name = DECL_SECTION_NAME (decl);
1613
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);
1618
1619 name = ACONCAT ((prefix, name, NULL));
1620 return get_named_section (decl, name, 0);
1621 }
1622
1623 #undef TARGET_SECTION_TYPE_FLAGS
1624 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1625
1626 unsigned int
1627 msp430_section_type_flags (tree decl, const char * name, int reloc)
1628 {
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);
1635
1636 return default_section_type_flags (decl, name, reloc);
1637 }
1638
1639 #undef TARGET_ASM_UNIQUE_SECTION
1640 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1641
1642 static void
1643 msp430_unique_section (tree decl, int reloc)
1644 {
1645 gcc_assert (decl != NULL_TREE);
1646
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))
1650 {
1651 set_decl_section_name (decl, ".lowtext");
1652 return;
1653 }
1654
1655 default_unique_section (decl, reloc);
1656
1657 const char * prefix;
1658
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
1665 )
1666 return;
1667
1668 const char * dec_name = DECL_SECTION_NAME (decl);
1669 char * name = ACONCAT ((prefix, dec_name, NULL));
1670
1671 set_decl_section_name (decl, name);
1672 }
1673
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. */
1677
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)
1684 {
1685 if (msp430_data_region == ANY)
1686 {
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);
1691 }
1692 else
1693 {
1694 section * sec;
1695
1696 if (decl)
1697 sec = msp430_select_section (decl, 0, align);
1698 else
1699 switch (msp430_data_region)
1700 {
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 ();
1706 }
1707 gcc_assert (sec != NULL);
1708
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);
1715 }
1716 }
1717
1718 bool
1719 msp430_do_not_relax_short_jumps (void)
1720 {
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);
1731 }
1732
1733 enum msp430_builtin
1734 {
1735 MSP430_BUILTIN_BIC_SR,
1736 MSP430_BUILTIN_BIS_SR,
1737 MSP430_BUILTIN_DELAY_CYCLES,
1738 MSP430_BUILTIN_max
1739 };
1740
1741 static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max];
1742
1743 static void
1744 msp430_init_builtins (void)
1745 {
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);
1748
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);
1752
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);
1756
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);
1760 }
1761
1762 static tree
1763 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
1764 {
1765 switch (code)
1766 {
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;
1773 }
1774 }
1775
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)
1780 {
1781 switch (c)
1782 {
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;
1793 }
1794 }
1795
1796 static rtx
1797 msp430_expand_delay_cycles (rtx arg)
1798 {
1799 HOST_WIDE_INT i, c, n;
1800 /* extra cycles for MSP430X instructions */
1801 #define CYCX(M,X) (msp430x ? (X) : (M))
1802
1803 if (GET_CODE (arg) != CONST_INT)
1804 {
1805 error ("__delay_cycles() only takes constant arguments");
1806 return NULL_RTX;
1807 }
1808
1809 c = INTVAL (arg);
1810
1811 if (HOST_BITS_PER_WIDE_INT > 32)
1812 {
1813 if (c < 0)
1814 {
1815 error ("__delay_cycles only takes non-negative cycle counts.");
1816 return NULL_RTX;
1817 }
1818 }
1819
1820 emit_insn (gen_delay_cycles_start (arg));
1821
1822 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
1823 if (c > 3 * 0xffff + CYCX (7, 10))
1824 {
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))
1828 {
1829 i = 0x10000;
1830 c -= CYCX (14, 16) + 7 * 0x10000;
1831 i += c / 4;
1832 c %= 4;
1833 if ((unsigned long long) i > 0xffffffffULL)
1834 {
1835 error ("__delay_cycles is limited to 32-bit loop counts.");
1836 return NULL_RTX;
1837 }
1838 }
1839 else
1840 {
1841 i = (c - CYCX (14, 16)) / 7;
1842 c -= CYCX (14, 16) + i * 7;
1843 }
1844
1845 if (cg_magic_constant (i & 0xffff))
1846 c ++;
1847 if (cg_magic_constant ((i >> 16) & 0xffff))
1848 c ++;
1849
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)));
1854 }
1855
1856 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */
1857 if (c > 12)
1858 {
1859 n = c;
1860 i = (c - CYCX (7, 10)) / 3;
1861 c -= CYCX (7, 10) + i * 3;
1862
1863 if (cg_magic_constant (i))
1864 c ++;
1865
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)));
1870 }
1871
1872 while (c > 1)
1873 {
1874 emit_insn (gen_delay_cycles_2 ());
1875 c -= 2;
1876 }
1877
1878 if (c)
1879 {
1880 emit_insn (gen_delay_cycles_1 ());
1881 c -= 1;
1882 }
1883
1884 emit_insn (gen_delay_cycles_end (arg));
1885
1886 return NULL_RTX;
1887 }
1888
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)
1895 {
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));
1899
1900 if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
1901 return msp430_expand_delay_cycles (arg1);
1902
1903 if (! msp430_is_interrupt_func ())
1904 {
1905 error ("MSP430 builtin functions only work inside interrupt handlers");
1906 return NULL_RTX;
1907 }
1908
1909 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
1910 arg1 = force_reg (mode, arg1);
1911
1912 switch (fcode)
1913 {
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;
1919 }
1920 return NULL_RTX;
1921 }
1922
1923 #undef TARGET_INIT_BUILTINS
1924 #define TARGET_INIT_BUILTINS msp430_init_builtins
1925
1926 #undef TARGET_EXPAND_BUILTIN
1927 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
1928
1929 #undef TARGET_BUILTIN_DECL
1930 #define TARGET_BUILTIN_DECL msp430_builtin_decl
1931
1932 void
1933 msp430_expand_prologue (void)
1934 {
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;
1943
1944 if (is_naked_func ())
1945 {
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;
1950 }
1951
1952 emit_insn (gen_prologue_start_marker ());
1953
1954 if (is_critical_func ())
1955 {
1956 emit_insn (gen_push_intr_state ());
1957 emit_insn (gen_disable_interrupts ());
1958 }
1959 else if (is_reentrant_func ())
1960 emit_insn (gen_disable_interrupts ());
1961
1962 if (!cfun->machine->computed)
1963 msp430_compute_frame_info ();
1964
1965 if (flag_stack_usage_info)
1966 current_function_static_stack_size = cfun->machine->framesize;
1967
1968 if (crtl->args.pretend_args_size)
1969 {
1970 rtx note;
1971
1972 gcc_assert (crtl->args.pretend_args_size == 2);
1973
1974 p = emit_insn (gen_grow_and_swap ());
1975
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);
1980
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);
1989 }
1990
1991 for (i = 15; i >= 4; i--)
1992 if (cfun->machine->need_to_save [i])
1993 {
1994 int seq, count;
1995 rtx note;
1996
1997 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
1998 ;
1999 count = i - seq;
2000
2001 if (msp430x)
2002 {
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))));
2006
2007 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2008
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)))));
2014
2015 /* *sp-- = R[i-j] */
2016 /* sp+N R10
2017 ...
2018 sp R4 */
2019 for (j = 0; j < count; j ++)
2020 {
2021 rtx addr;
2022 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2023
2024 if (ofs)
2025 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2026 else
2027 addr = stack_pointer_rtx;
2028
2029 XVECEXP (note, 0, j + 1) =
2030 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2031 gen_rtx_REG (Pmode, i - j)) );
2032 }
2033
2034 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2035 i -= count - 1;
2036 }
2037 else
2038 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2039 }
2040
2041 if (frame_pointer_needed)
2042 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2043
2044 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2045
2046 increment_stack (- fs);
2047
2048 emit_insn (gen_prologue_end_marker ());
2049 }
2050
2051 void
2052 msp430_expand_epilogue (int is_eh)
2053 {
2054 int i;
2055 int fs;
2056 int helper_n = 0;
2057
2058 if (is_naked_func ())
2059 {
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;
2064 }
2065
2066 if (cfun->machine->need_to_save [10])
2067 {
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])
2072 {
2073 helper_n = 10 - i;
2074 for (; i >= 4; i--)
2075 if (cfun->machine->need_to_save [i])
2076 {
2077 helper_n = 0;
2078 break;
2079 }
2080 break;
2081 }
2082 }
2083
2084 emit_insn (gen_epilogue_start_marker ());
2085
2086 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), "main") == 0)
2087 emit_insn (gen_msp430_refsym_need_exit ());
2088
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)));
2096
2097 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2098
2099 increment_stack (fs);
2100
2101 if (is_eh)
2102 {
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;
2109
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);
2116 }
2117
2118 for (i = 4; i <= 15; i++)
2119 if (cfun->machine->need_to_save [i])
2120 {
2121 int seq, count;
2122
2123 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
2124 ;
2125 count = seq - i;
2126
2127 if (msp430x)
2128 {
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;
2134 }
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)
2143 {
2144 emit_insn (gen_epilogue_helper (GEN_INT (helper_n)));
2145 return;
2146 }
2147 else
2148 emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
2149 }
2150
2151 if (is_eh)
2152 {
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));
2157 }
2158
2159 if (crtl->args.pretend_args_size)
2160 emit_insn (gen_swap_and_shrink ());
2161
2162 if (is_critical_func ())
2163 emit_insn (gen_pop_intr_state ());
2164 else if (is_reentrant_func ())
2165 emit_insn (gen_enable_interrupts ());
2166
2167 emit_jump_insn (gen_msp_return ());
2168 }
2169
2170 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2171 m32c_emit_eh_epilogue. */
2172 rtx
2173 msp430_eh_return_stackadj_rtx (void)
2174 {
2175 if (!cfun->machine->eh_stack_adjust)
2176 {
2177 rtx sa;
2178
2179 sa = gen_rtx_REG (Pmode, 15);
2180 cfun->machine->eh_stack_adjust = sa;
2181 }
2182 return cfun->machine->eh_stack_adjust;
2183 }
2184
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)
2189 {
2190 /* These are all Pmode */
2191 rtx ap, sa, ra, tmp;
2192
2193 ap = arg_pointer_rtx;
2194 sa = msp430_eh_return_stackadj_rtx ();
2195 ra = eh_handler;
2196
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);
2202 }
2203
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)
2208 {
2209 int i;
2210 rtx addr = expand_normal (address);
2211 rtx mem = gen_rtx_MEM (BLKmode, addr);
2212
2213 if (!msp430x)
2214 return;
2215
2216 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2217 {
2218 unsigned int dnum = DWARF_FRAME_REGNUM (i);
2219 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
2220
2221 if (rnum < DWARF_FRAME_REGISTERS)
2222 {
2223 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
2224
2225 emit_move_insn (adjust_address (mem, QImode, offset),
2226 gen_int_mode (4, QImode));
2227 }
2228 }
2229 }
2230
2231 /* This is a list of MD patterns that implement fixed-count shifts. */
2232 static struct
2233 {
2234 const char *name;
2235 int count;
2236 int need_430x;
2237 rtx (*genfunc)(rtx,rtx);
2238 }
2239 const_shift_helpers[] =
2240 {
2241 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2242
2243 CSH ("slli", 1, 1, slli_1),
2244 CSH ("slll", 1, 1, slll_1),
2245 CSH ("slll", 2, 1, slll_2),
2246
2247 CSH ("srai", 1, 0, srai_1),
2248 CSH ("sral", 1, 0, sral_1),
2249 CSH ("sral", 2, 0, sral_2),
2250
2251 CSH ("srll", 1, 0, srll_1),
2252 CSH ("srll", 2, 1, srll_2x),
2253 { 0, 0, 0, 0 }
2254 #undef CSH
2255 };
2256
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)
2263 {
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;
2272
2273 if (CONST_INT_P (operands[2]))
2274 {
2275 int i;
2276
2277 for (i=0; const_shift_helpers[i].name; i++)
2278 {
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)
2282 {
2283 emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1]));
2284 return;
2285 }
2286 }
2287 }
2288
2289 if (arg1mode == VOIDmode)
2290 arg1mode = arg0mode;
2291 if (arg2mode == VOIDmode)
2292 arg2mode = arg0mode;
2293
2294 if (arg1mode == SImode)
2295 {
2296 arg2 = 14;
2297 arg1sz = 2;
2298 }
2299
2300 if (const_variants
2301 && CONST_INT_P (operands[2])
2302 && INTVAL (operands[2]) >= 1
2303 && INTVAL (operands[2]) <= 15)
2304 {
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]));
2309 }
2310
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]);
2316
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;
2322
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);
2328
2329 emit_move_insn (operands[0],
2330 gen_rtx_REG (arg0mode, 12));
2331 }
2332
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)
2336 {
2337 /* constants we're looking for, not constants which are allowed. */
2338 int const_op_idx = 1;
2339
2340 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
2341 const_op_idx = 2;
2342
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]);
2346 }
2347
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. */
2351 rtx
2352 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
2353 {
2354 rtx rv;
2355
2356 if (GET_CODE (r) == SUBREG
2357 && SUBREG_BYTE (r) == 0)
2358 {
2359 rtx ireg = SUBREG_REG (r);
2360 machine_mode imode = GET_MODE (ireg);
2361
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);
2369 }
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)
2375 {
2376 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
2377 rv = gen_rtx_CONST (HImode, r);
2378 }
2379 else
2380 rv = simplify_gen_subreg (mode, r, omode, byte);
2381
2382 if (!rv)
2383 gcc_unreachable ();
2384
2385 return rv;
2386 }
2387
2388 /* Called by movsi_x to generate the HImode operands. */
2389 void
2390 msp430_split_movsi (rtx *operands)
2391 {
2392 rtx op00, op02, op10, op12;
2393
2394 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
2395 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
2396
2397 if (GET_CODE (operands[1]) == CONST
2398 || GET_CODE (operands[1]) == SYMBOL_REF)
2399 {
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);
2404 }
2405 else
2406 {
2407 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
2408 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
2409 }
2410
2411 if (rtx_equal_p (operands[0], operands[1]))
2412 {
2413 operands[2] = op02;
2414 operands[4] = op12;
2415 operands[3] = op00;
2416 operands[5] = op10;
2417 }
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))
2423 )
2424 {
2425 operands[2] = op02;
2426 operands[4] = op12;
2427 operands[3] = op00;
2428 operands[5] = op10;
2429 }
2430 else
2431 {
2432 operands[2] = op00;
2433 operands[4] = op10;
2434 operands[3] = op02;
2435 operands[5] = op12;
2436 }
2437 }
2438
2439 \f
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
2444 {
2445 char const * const gcc_name;
2446 char const * const ti_name;
2447 }
2448 helper_function_name_mappings [] =
2449 {
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" },
2477
2478 /* Floating point comparisons. */
2479 /* GCC uses individual functions for each comparison, TI uses one
2480 compare <=> function. */
2481
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 */
2492
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
2502
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" },
2515
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. */
2521
2522 { NULL, NULL }
2523 };
2524
2525 /* Returns true if the current MCU supports an F5xxx series
2526 hardware multiper. */
2527
2528 bool
2529 msp430_use_f5_series_hwmult (void)
2530 {
2531 static const char * cached_match = NULL;
2532 static bool cached_result;
2533
2534 if (msp430_hwmult_type == F5SERIES)
2535 return true;
2536
2537 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2538 return false;
2539
2540 if (target_mcu == cached_match)
2541 return cached_result;
2542
2543 cached_match = target_mcu;
2544
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;
2551
2552 static const char * known_f5_mult_mcus [] =
2553 {
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"
2561 };
2562 int i;
2563
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;
2567
2568 return cached_result = false;
2569 }
2570
2571 /* Returns true if the current MCU has a second generation
2572 32-bit hardware multiplier. */
2573
2574 static bool
2575 use_32bit_hwmult (void)
2576 {
2577 static const char * known_32bit_mult_mcus [] =
2578 {
2579 "msp430f4783", "msp430f4793", "msp430f4784",
2580 "msp430f4794", "msp430f47126", "msp430f47127",
2581 "msp430f47163", "msp430f47173", "msp430f47183",
2582 "msp430f47193", "msp430f47166", "msp430f47176",
2583 "msp430f47186", "msp430f47196", "msp430f47167",
2584 "msp430f47177", "msp430f47187", "msp430f47197"
2585 };
2586 static const char * cached_match = NULL;
2587 static bool cached_result;
2588 int i;
2589
2590 if (msp430_hwmult_type == LARGE)
2591 return true;
2592
2593 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2594 return false;
2595
2596 if (target_mcu == cached_match)
2597 return cached_result;
2598
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;
2603
2604 return cached_result = false;
2605 }
2606
2607 /* Returns true if the current MCU does not have a
2608 hardware multiplier of any kind. */
2609
2610 static bool
2611 msp430_no_hwmult (void)
2612 {
2613 static const char * known_nomult_mcus [] =
2614 {
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"
2670 };
2671 static const char * cached_match = NULL;
2672 static bool cached_result;
2673 int i;
2674
2675 if (msp430_hwmult_type == NONE)
2676 return true;
2677
2678 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2679 return false;
2680
2681 if (target_mcu == cached_match)
2682 return cached_result;
2683
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;
2688
2689 return cached_result = false;
2690 }
2691
2692 /* This function does the same as the default, but it will replace GCC
2693 function names with the MSPABI-specified ones. */
2694
2695 void
2696 msp430_output_labelref (FILE *file, const char *name)
2697 {
2698 int i;
2699
2700 for (i = 0; helper_function_name_mappings [i].gcc_name; i++)
2701 if (strcmp (helper_function_name_mappings [i].gcc_name, name) == 0)
2702 {
2703 name = helper_function_name_mappings [i].ti_name;
2704 break;
2705 }
2706
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)
2710 {
2711 if (strcmp ("__mspabi_mpyi", name) == 0)
2712 {
2713 if (msp430_use_f5_series_hwmult ())
2714 name = "__mulhi2_f5";
2715 else if (! msp430_no_hwmult ())
2716 name = "__mulhi2";
2717 }
2718 else if (strcmp ("__mspabi_mpyl", name) == 0)
2719 {
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";
2726 }
2727 }
2728
2729 fputs (name, file);
2730 }
2731
2732 /* Common code for msp430_print_operand... */
2733
2734 static void
2735 msp430_print_operand_raw (FILE * file, rtx op)
2736 {
2737 HOST_WIDE_INT i;
2738
2739 switch (GET_CODE (op))
2740 {
2741 case REG:
2742 fprintf (file, "%s", reg_names [REGNO (op)]);
2743 break;
2744
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;
2752
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;
2760
2761 default:
2762 print_rtl (file, op);
2763 break;
2764 }
2765 }
2766
2767 #undef TARGET_PRINT_OPERAND_ADDRESS
2768 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
2769
2770 /* Output to stdio stream FILE the assembler syntax for an
2771 instruction operand that is a memory reference whose address
2772 is ADDR. */
2773
2774 static void
2775 msp430_print_operand_addr (FILE * file, rtx addr)
2776 {
2777 switch (GET_CODE (addr))
2778 {
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;
2784
2785 case REG:
2786 fprintf (file, "@");
2787 break;
2788
2789 case CONST:
2790 case CONST_INT:
2791 case SYMBOL_REF:
2792 case LABEL_REF:
2793 fprintf (file, "&");
2794 break;
2795
2796 default:
2797 break;
2798 }
2799
2800 msp430_print_operand_raw (file, addr);
2801 }
2802
2803 #undef TARGET_PRINT_OPERAND
2804 #define TARGET_PRINT_OPERAND msp430_print_operand
2805
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. */
2824
2825 static void
2826 msp430_print_operand (FILE * file, rtx op, int letter)
2827 {
2828 rtx addr;
2829
2830 /* We can't use c, n, a, or l. */
2831 switch (letter)
2832 {
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)
2845 {
2846 /* Inverse of constants */
2847 int i = INTVAL (op);
2848 fprintf (file, "%d", ~i);
2849 return;
2850 }
2851 op = XEXP (op, 0);
2852 break;
2853 case 'r': /* Conditional jump where the condition is reversed. */
2854 switch (GET_CODE (op))
2855 {
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;
2870 }
2871 return;
2872 case 'R': /* Conditional jump where the operands are reversed. */
2873 switch (GET_CODE (op))
2874 {
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;
2882 }
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))
2890 {
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;
2897 }
2898 case 'A':
2899 case 'L': /* Low half. */
2900 switch (GET_CODE (op))
2901 {
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 ();
2914 }
2915 break;
2916 case 'B':
2917 case 'H': /* high half */
2918 switch (GET_CODE (op))
2919 {
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 ();
2933 }
2934 break;
2935 case 'C':
2936 switch (GET_CODE (op))
2937 {
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 ();
2951 }
2952 break;
2953 case 'D':
2954 switch (GET_CODE (op))
2955 {
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 ();
2969 }
2970 break;
2971
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;
2980
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;
2986
2987 case 'Q':
2988 /* Likewise, for BR -> BRA. */
2989 if (TARGET_LARGE)
2990 fprintf (file, "A");
2991 return;
2992
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;
3001
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;
3009 }
3010
3011 switch (GET_CODE (op))
3012 {
3013 case REG:
3014 msp430_print_operand_raw (file, op);
3015 break;
3016
3017 case MEM:
3018 addr = XEXP (op, 0);
3019 msp430_print_operand_addr (file, addr);
3020 break;
3021
3022 case CONST:
3023 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
3024 {
3025 op = XEXP (op, 0);
3026 switch (INTVAL (XEXP (op, 2)))
3027 {
3028 case 0:
3029 fprintf (file, "#lo (");
3030 msp430_print_operand_raw (file, XEXP (op, 0));
3031 fprintf (file, ")");
3032 break;
3033
3034 case 16:
3035 fprintf (file, "#hi (");
3036 msp430_print_operand_raw (file, XEXP (op, 0));
3037 fprintf (file, ")");
3038 break;
3039
3040 default:
3041 output_operand_lossage ("invalid zero extract");
3042 break;
3043 }
3044 break;
3045 }
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;
3054
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;
3061
3062 default:
3063 print_rtl (file, op);
3064 break;
3065 }
3066 }
3067
3068 \f
3069 /* Frame stuff. */
3070
3071 rtx
3072 msp430_return_addr_rtx (int count)
3073 {
3074 int ra_size;
3075 if (count)
3076 return NULL_RTX;
3077
3078 ra_size = TARGET_LARGE ? 4 : 2;
3079 if (crtl->args.pretend_args_size)
3080 ra_size += 2;
3081
3082 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size)));
3083 }
3084
3085 rtx
3086 msp430_incoming_return_addr_rtx (void)
3087 {
3088 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
3089 }
3090 \f
3091 /* Instruction generation stuff. */
3092
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. */
3096
3097 const char *
3098 msp430x_extendhisi (rtx * operands)
3099 {
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. */
3103
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:
3107
3108 MOV.W %1, %L0
3109 MOV.W %1, r12
3110 CALL __mspabi_srai_15
3111 MOV.W r12, %H0
3112
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. */
3116
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. */
3120
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. */
3123 }
3124
3125 /* Likewise for logical right shifts. */
3126 const char *
3127 msp430x_logical_shift_right (rtx amount)
3128 {
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));
3134
3135 if (INTVAL (amount) <= 0
3136 || INTVAL (amount) >= 16)
3137 return "# nop logical shift.";
3138
3139 if (INTVAL (amount) > 0
3140 && INTVAL (amount) < 5)
3141 return "rrum.w\t%2, %0"; /* Two bytes. */
3142
3143 if (INTVAL (amount) > 4
3144 && INTVAL (amount) < 9)
3145 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
3146
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. */
3151 }
3152 \f
3153 struct gcc_target targetm = TARGET_INITIALIZER;
3154
3155 #include "gt-msp430.h"