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