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