]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/msp430/msp430.c
* config/msp430/msp430.c (msp430_asm_integer): Support addition
[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 || c == PLUS || c == MINUS)
981 {
982 fprintf (asm_out_file, "\t.long\t");
983 output_addr_const (asm_out_file, x);
984 fputc ('\n', asm_out_file);
985 return true;
986 }
987 break;
988 }
989 return default_assemble_integer (x, size, aligned_p);
990 }
991
992 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
993 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
994 static bool
995 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
996 {
997 debug_rtx(x);
998 return false;
999 }
1000
1001 #undef TARGET_LEGITIMATE_CONSTANT_P
1002 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1003
1004 static bool
1005 msp430_legitimate_constant (machine_mode mode, rtx x)
1006 {
1007 return ! CONST_INT_P (x)
1008 || mode != PSImode
1009 /* GCC does not know the width of the PSImode, so make
1010 sure that it does not try to use a constant value that
1011 is out of range. */
1012 || (INTVAL (x) < (1 << 20) && INTVAL (x) >= (-1 << 20));
1013 }
1014
1015 \f
1016 #undef TARGET_RTX_COSTS
1017 #define TARGET_RTX_COSTS msp430_rtx_costs
1018
1019 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED,
1020 int code,
1021 int outer_code ATTRIBUTE_UNUSED,
1022 int opno ATTRIBUTE_UNUSED,
1023 int * total,
1024 bool speed ATTRIBUTE_UNUSED)
1025 {
1026 switch (code)
1027 {
1028 case SIGN_EXTEND:
1029 if (GET_MODE (x) == SImode && outer_code == SET)
1030 {
1031 *total = COSTS_N_INSNS (4);
1032 return true;
1033 }
1034 break;
1035 case ASHIFT:
1036 case ASHIFTRT:
1037 case LSHIFTRT:
1038 if (!msp430x)
1039 {
1040 *total = COSTS_N_INSNS (100);
1041 return true;
1042 }
1043 break;
1044 }
1045 return false;
1046 }
1047 \f
1048 /* Function Entry and Exit */
1049
1050 /* The MSP430 call frame looks like this:
1051
1052 <higher addresses>
1053 +--------------------+
1054 | |
1055 | Stack Arguments |
1056 | |
1057 +--------------------+ <-- "arg pointer"
1058 | |
1059 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE)
1060 | |
1061 +--------------------+
1062 | SR if this func has|
1063 | been called via an |
1064 | interrupt. |
1065 +--------------------+ <-- SP before prologue, also AP
1066 | |
1067 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1068 | |
1069 +--------------------+ <-- "frame pointer"
1070 | |
1071 | Locals |
1072 | |
1073 +--------------------+
1074 | |
1075 | Outgoing Args |
1076 | |
1077 +--------------------+ <-- SP during function
1078 <lower addresses>
1079
1080 */
1081
1082 /* We use this to wrap all emitted insns in the prologue, so they get
1083 the "frame-related" (/f) flag set. */
1084 static rtx
1085 F (rtx x)
1086 {
1087 RTX_FRAME_RELATED_P (x) = 1;
1088 return x;
1089 }
1090
1091 /* This is the one spot that decides if a register is to be saved and
1092 restored in the prologue/epilogue. */
1093 static bool
1094 msp430_preserve_reg_p (int regno)
1095 {
1096 /* PC, SP, SR, and the constant generator. */
1097 if (regno <= 3)
1098 return false;
1099
1100 /* FIXME: add interrupt, EH, etc. */
1101 if (crtl->calls_eh_return)
1102 return true;
1103
1104 /* Shouldn't be more than the above, but just in case... */
1105 if (fixed_regs [regno])
1106 return false;
1107
1108 /* Interrupt handlers save all registers they use, even
1109 ones which are call saved. If they call other functions
1110 then *every* register is saved. */
1111 if (msp430_is_interrupt_func ())
1112 return ! crtl->is_leaf || df_regs_ever_live_p (regno);
1113
1114 if (!call_used_regs [regno]
1115 && df_regs_ever_live_p (regno))
1116 return true;
1117
1118 return false;
1119 }
1120
1121 /* Compute all the frame-related fields in our machine_function
1122 structure. */
1123 static void
1124 msp430_compute_frame_info (void)
1125 {
1126 int i;
1127
1128 cfun->machine->computed = 1;
1129 cfun->machine->framesize_regs = 0;
1130 cfun->machine->framesize_locals = get_frame_size ();
1131 cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
1132
1133 for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1134 if (msp430_preserve_reg_p (i))
1135 {
1136 cfun->machine->need_to_save [i] = 1;
1137 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1138 }
1139 else
1140 cfun->machine->need_to_save [i] = 0;
1141
1142 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1143 cfun->machine->framesize_locals ++;
1144
1145 cfun->machine->framesize = (cfun->machine->framesize_regs
1146 + cfun->machine->framesize_locals
1147 + cfun->machine->framesize_outgoing);
1148 }
1149
1150 /* Attribute Handling. */
1151
1152 const char * const ATTR_INTR = "interrupt";
1153 const char * const ATTR_WAKEUP = "wakeup";
1154 const char * const ATTR_NAKED = "naked";
1155 const char * const ATTR_REENT = "reentrant";
1156 const char * const ATTR_CRIT = "critical";
1157 const char * const ATTR_LOWER = "lower";
1158 const char * const ATTR_UPPER = "upper";
1159 const char * const ATTR_EITHER = "either";
1160
1161 static inline bool
1162 has_attr (const char * attr, tree decl)
1163 {
1164 if (decl == NULL_TREE)
1165 return false;
1166 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1167 }
1168
1169 static bool
1170 is_interrupt_func (tree decl = current_function_decl)
1171 {
1172 return has_attr (ATTR_INTR, decl);
1173 }
1174
1175 /* Returns true if the current function has the "interrupt" attribute. */
1176
1177 bool
1178 msp430_is_interrupt_func (void)
1179 {
1180 return is_interrupt_func (current_function_decl);
1181 }
1182
1183 static bool
1184 is_wakeup_func (tree decl = current_function_decl)
1185 {
1186 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1187 }
1188
1189 static inline bool
1190 is_naked_func (tree decl = current_function_decl)
1191 {
1192 return has_attr (ATTR_NAKED, decl);
1193 }
1194
1195 static inline bool
1196 is_reentrant_func (tree decl = current_function_decl)
1197 {
1198 return has_attr (ATTR_REENT, decl);
1199 }
1200
1201 static inline bool
1202 is_critical_func (tree decl = current_function_decl)
1203 {
1204 return has_attr (ATTR_CRIT, decl);
1205 }
1206
1207 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1208 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args
1209
1210 static bool
1211 msp430_allocate_stack_slots_for_args (void)
1212 {
1213 /* Naked functions should not allocate stack slots for arguments. */
1214 return ! is_naked_func ();
1215 }
1216
1217 /* Verify MSP430 specific attributes. */
1218 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1219
1220 static tree
1221 msp430_attr (tree * node,
1222 tree name,
1223 tree args,
1224 int flags ATTRIBUTE_UNUSED,
1225 bool * no_add_attrs)
1226 {
1227 gcc_assert (DECL_P (* node));
1228
1229 if (args != NULL)
1230 {
1231 gcc_assert (TREE_NAME_EQ (name, ATTR_INTR));
1232
1233 tree value = TREE_VALUE (args);
1234
1235 switch (TREE_CODE (value))
1236 {
1237 case STRING_CST:
1238 if ( strcmp (TREE_STRING_POINTER (value), "reset")
1239 && strcmp (TREE_STRING_POINTER (value), "nmi")
1240 && strcmp (TREE_STRING_POINTER (value), "watchdog"))
1241 /* Allow the attribute to be added - the linker script
1242 being used may still recognise this name. */
1243 warning (OPT_Wattributes,
1244 "unrecognised interrupt vector argument of %qE attribute",
1245 name);
1246 break;
1247
1248 case INTEGER_CST:
1249 if (wi::gtu_p (value, 63))
1250 /* Allow the attribute to be added - the linker script
1251 being used may still recognise this value. */
1252 warning (OPT_Wattributes,
1253 "numeric argument of %qE attribute must be in range 0..63",
1254 name);
1255 break;
1256
1257 default:
1258 warning (OPT_Wattributes,
1259 "argument of %qE attribute is not a string constant or number",
1260 name);
1261 *no_add_attrs = true;
1262 break;
1263 }
1264 }
1265
1266 const char * message = NULL;
1267
1268 if (TREE_CODE (* node) != FUNCTION_DECL)
1269 {
1270 message = "%qE attribute only applies to functions";
1271 }
1272 else if (TREE_NAME_EQ (name, ATTR_INTR))
1273 {
1274 if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE
1275 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node))))
1276 message = "interrupt handlers must be void";
1277 }
1278 else if (TREE_NAME_EQ (name, ATTR_REENT))
1279 {
1280 if (is_naked_func (* node))
1281 message = "naked functions cannot be reentrant";
1282 else if (is_critical_func (* node))
1283 message = "critical functions cannot be reentrant";
1284 }
1285 else if (TREE_NAME_EQ (name, ATTR_CRIT))
1286 {
1287 if (is_naked_func (* node))
1288 message = "naked functions cannot be critical";
1289 else if (is_reentrant_func (* node))
1290 message = "reentranct functions cannot be critical";
1291 }
1292 else if (TREE_NAME_EQ (name, ATTR_NAKED))
1293 {
1294 if (is_critical_func (* node))
1295 message = "critical functions cannot be naked";
1296 else if (is_reentrant_func (* node))
1297 message = "reentrant functions cannot be naked";
1298 }
1299
1300 if (message)
1301 {
1302 warning (OPT_Wattributes, message, name);
1303 * no_add_attrs = true;
1304 }
1305
1306 return NULL_TREE;
1307 }
1308
1309 static tree
1310 msp430_section_attr (tree * node,
1311 tree name,
1312 tree args,
1313 int flags ATTRIBUTE_UNUSED,
1314 bool * no_add_attrs ATTRIBUTE_UNUSED)
1315 {
1316 gcc_assert (DECL_P (* node));
1317 gcc_assert (args == NULL);
1318
1319 const char * message = NULL;
1320
1321 if (TREE_NAME_EQ (name, ATTR_UPPER))
1322 {
1323 if (has_attr (ATTR_LOWER, * node))
1324 message = "already marked with 'lower' attribute";
1325 else if (has_attr (ATTR_EITHER, * node))
1326 message = "already marked with 'either' attribute";
1327 else if (! msp430x)
1328 message = "upper attribute needs a 430X cpu";
1329 }
1330 else if (TREE_NAME_EQ (name, ATTR_LOWER))
1331 {
1332 if (has_attr (ATTR_UPPER, * node))
1333 message = "already marked with 'upper' attribute";
1334 else if (has_attr (ATTR_EITHER, * node))
1335 message = "already marked with 'either' attribute";
1336 }
1337 else
1338 {
1339 gcc_assert (TREE_NAME_EQ (name, ATTR_EITHER));
1340
1341 if (has_attr (ATTR_LOWER, * node))
1342 message = "already marked with 'lower' attribute";
1343 else if (has_attr (ATTR_UPPER, * node))
1344 message = "already marked with 'upper' attribute";
1345 }
1346
1347 if (message)
1348 {
1349 warning (OPT_Wattributes, message, name);
1350 * no_add_attrs = true;
1351 }
1352
1353 return NULL_TREE;
1354 }
1355
1356 #undef TARGET_ATTRIBUTE_TABLE
1357 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table
1358
1359 /* Table of MSP430-specific attributes. */
1360 const struct attribute_spec msp430_attribute_table[] =
1361 {
1362 /* Name min_num_args type_req, affects_type_identity
1363 max_num_args, fn_type_req
1364 decl_req handler. */
1365 { ATTR_INTR, 0, 1, true, false, false, msp430_attr, false },
1366 { ATTR_NAKED, 0, 0, true, false, false, msp430_attr, false },
1367 { ATTR_REENT, 0, 0, true, false, false, msp430_attr, false },
1368 { ATTR_CRIT, 0, 0, true, false, false, msp430_attr, false },
1369 { ATTR_WAKEUP, 0, 0, true, false, false, msp430_attr, false },
1370
1371 { ATTR_LOWER, 0, 0, true, false, false, msp430_section_attr, false },
1372 { ATTR_UPPER, 0, 0, true, false, false, msp430_section_attr, false },
1373 { ATTR_EITHER, 0, 0, true, false, false, msp430_section_attr, false },
1374
1375 { NULL, 0, 0, false, false, false, NULL, false }
1376 };
1377
1378 #undef TARGET_ASM_FUNCTION_PROLOGUE
1379 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
1380
1381 static void
1382 msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
1383 {
1384 int r, n;
1385
1386 fprintf (outfile, "; start of function\n");
1387
1388 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
1389 {
1390 fprintf (outfile, "; attributes: ");
1391 if (is_naked_func ())
1392 fprintf (outfile, "naked ");
1393 if (msp430_is_interrupt_func ())
1394 fprintf (outfile, "interrupt ");
1395 if (is_reentrant_func ())
1396 fprintf (outfile, "reentrant ");
1397 if (is_critical_func ())
1398 fprintf (outfile, "critical ");
1399 if (is_wakeup_func ())
1400 fprintf (outfile, "wakeup ");
1401 fprintf (outfile, "\n");
1402 }
1403
1404 fprintf (outfile, "; framesize_regs: %d\n", cfun->machine->framesize_regs);
1405 fprintf (outfile, "; framesize_locals: %d\n", cfun->machine->framesize_locals);
1406 fprintf (outfile, "; framesize_outgoing: %d\n", cfun->machine->framesize_outgoing);
1407 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
1408 fprintf (outfile, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM));
1409 fprintf (outfile, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM));
1410
1411 n = 0;
1412 fprintf (outfile, "; saved regs:");
1413 for (r = 0; r < ARG_POINTER_REGNUM; r++)
1414 if (cfun->machine->need_to_save [r])
1415 {
1416 fprintf (outfile, " %s", reg_names [r]);
1417 n = 1;
1418 }
1419 if (n == 0)
1420 fprintf (outfile, "(none)");
1421 fprintf (outfile, "\n");
1422 }
1423
1424 /* Common code to change the stack pointer. */
1425 static void
1426 increment_stack (HOST_WIDE_INT amount)
1427 {
1428 rtx inc;
1429 rtx sp = stack_pointer_rtx;
1430
1431 if (amount == 0)
1432 return;
1433
1434 if (amount < 0)
1435 {
1436 inc = GEN_INT (- amount);
1437 if (TARGET_LARGE)
1438 F (emit_insn (gen_subpsi3 (sp, sp, inc)));
1439 else
1440 F (emit_insn (gen_subhi3 (sp, sp, inc)));
1441 }
1442 else
1443 {
1444 inc = GEN_INT (amount);
1445 if (TARGET_LARGE)
1446 emit_insn (gen_addpsi3 (sp, sp, inc));
1447 else
1448 emit_insn (gen_addhi3 (sp, sp, inc));
1449 }
1450 }
1451
1452 void
1453 msp430_start_function (FILE *file, const char *name, tree decl)
1454 {
1455 tree int_attr;
1456
1457 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1458 if (int_attr != NULL_TREE)
1459 {
1460 tree intr_vector = TREE_VALUE (int_attr);
1461
1462 if (intr_vector != NULL_TREE)
1463 {
1464 char buf[101];
1465
1466 intr_vector = TREE_VALUE (intr_vector);
1467
1468 /* The interrupt attribute has a vector value. Turn this into a
1469 section name, switch to that section and put the address of
1470 the current function into that vector slot. Note msp430_attr()
1471 has already verified the vector name for us. */
1472 if (TREE_CODE (intr_vector) == STRING_CST)
1473 sprintf (buf, "__interrupt_vector_%.80s",
1474 TREE_STRING_POINTER (intr_vector));
1475 else /* TREE_CODE (intr_vector) == INTEGER_CST */
1476 sprintf (buf, "__interrupt_vector_%u",
1477 (unsigned int) TREE_INT_CST_LOW (intr_vector));
1478
1479 switch_to_section (get_section (buf, SECTION_CODE, decl));
1480 fputs ("\t.word\t", file);
1481 assemble_name (file, name);
1482 fputc ('\n', file);
1483 fputc ('\t', file);
1484 }
1485 }
1486
1487 switch_to_section (function_section (decl));
1488 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1489 }
1490
1491 static const char * const lower_prefix = ".lower";
1492 static const char * const upper_prefix = ".upper";
1493 static const char * const either_prefix = ".either";
1494
1495 /* Generate a prefix for a section name, based upon
1496 the region into which the object should be placed. */
1497
1498 static const char *
1499 gen_prefix (tree decl)
1500 {
1501 if (DECL_ONE_ONLY (decl))
1502 return NULL;
1503
1504 /* If the user has specified a particular section then do not use any prefix. */
1505 if (has_attr ("section", decl))
1506 return NULL;
1507
1508 /* If the object has __attribute__((lower)) then use the ".lower." prefix. */
1509 if (has_attr (ATTR_LOWER, decl))
1510 return lower_prefix;
1511
1512 /* If we are compiling for the MSP430 then we do not support the upper region. */
1513 if (! msp430x)
1514 return NULL;
1515
1516 if (has_attr (ATTR_UPPER, decl))
1517 return upper_prefix;
1518
1519 if (has_attr (ATTR_EITHER, decl))
1520 return either_prefix;
1521
1522 if (TREE_CODE (decl) == FUNCTION_DECL)
1523 {
1524 if (msp430_code_region == LOWER)
1525 return lower_prefix;
1526
1527 if (msp430_code_region == UPPER)
1528 return upper_prefix;
1529
1530 if (msp430_code_region == EITHER)
1531 return either_prefix;
1532 }
1533 else
1534 {
1535 if (msp430_data_region == LOWER)
1536 return lower_prefix;
1537
1538 if (msp430_data_region == UPPER)
1539 return upper_prefix;
1540
1541 if (msp430_data_region == EITHER)
1542 return either_prefix;
1543 }
1544
1545 return NULL;
1546 }
1547
1548 #undef TARGET_ASM_SELECT_SECTION
1549 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1550
1551 static section *
1552 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
1553 {
1554 gcc_assert (decl != NULL_TREE);
1555
1556 if (TREE_CODE (decl) == STRING_CST
1557 || TREE_CODE (decl) == CONSTRUCTOR
1558 || TREE_CODE (decl) == INTEGER_CST
1559 || TREE_CODE (decl) == VECTOR_CST
1560 || TREE_CODE (decl) == COMPLEX_CST)
1561 return default_select_section (decl, reloc, align);
1562
1563 /* In large mode we must make sure that interrupt handlers are put into
1564 low memory as the vector table only accepts 16-bit addresses. */
1565 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl))
1566 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
1567
1568 const char * prefix = gen_prefix (decl);
1569 if (prefix == NULL)
1570 {
1571 if (TREE_CODE (decl) == FUNCTION_DECL)
1572 return text_section;
1573 else
1574 return default_select_section (decl, reloc, align);
1575 }
1576
1577 const char * sec;
1578 switch (categorize_decl_for_section (decl, reloc))
1579 {
1580 case SECCAT_TEXT: sec = ".text"; break;
1581 case SECCAT_DATA: sec = ".data"; break;
1582 case SECCAT_BSS: sec = ".bss"; break;
1583 case SECCAT_RODATA: sec = ".rodata"; break;
1584
1585 case SECCAT_RODATA_MERGE_STR:
1586 case SECCAT_RODATA_MERGE_STR_INIT:
1587 case SECCAT_RODATA_MERGE_CONST:
1588 case SECCAT_SRODATA:
1589 case SECCAT_DATA_REL:
1590 case SECCAT_DATA_REL_LOCAL:
1591 case SECCAT_DATA_REL_RO:
1592 case SECCAT_DATA_REL_RO_LOCAL:
1593 case SECCAT_SDATA:
1594 case SECCAT_SBSS:
1595 case SECCAT_TDATA:
1596 case SECCAT_TBSS:
1597 return default_select_section (decl, reloc, align);
1598
1599 default:
1600 gcc_unreachable ();
1601 }
1602
1603 const char * dec_name = DECL_SECTION_NAME (decl);
1604 char * name = ACONCAT ((prefix, sec, dec_name, NULL));
1605
1606 return get_named_section (decl, name, 0);
1607 }
1608
1609 #undef TARGET_ASM_FUNCTION_SECTION
1610 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1611
1612 static section *
1613 msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit)
1614 {
1615 const char * name;
1616
1617 gcc_assert (DECL_SECTION_NAME (decl) != NULL);
1618 name = DECL_SECTION_NAME (decl);
1619
1620 const char * prefix = gen_prefix (decl);
1621 if (prefix == NULL
1622 || strncmp (name, prefix, strlen (prefix)) == 0)
1623 return default_function_section (decl, freq, startup, exit);
1624
1625 name = ACONCAT ((prefix, name, NULL));
1626 return get_named_section (decl, name, 0);
1627 }
1628
1629 #undef TARGET_SECTION_TYPE_FLAGS
1630 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1631
1632 unsigned int
1633 msp430_section_type_flags (tree decl, const char * name, int reloc)
1634 {
1635 if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0)
1636 name += strlen (lower_prefix);
1637 else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0)
1638 name += strlen (upper_prefix);
1639 else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
1640 name += strlen (either_prefix);
1641
1642 return default_section_type_flags (decl, name, reloc);
1643 }
1644
1645 #undef TARGET_ASM_UNIQUE_SECTION
1646 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1647
1648 static void
1649 msp430_unique_section (tree decl, int reloc)
1650 {
1651 gcc_assert (decl != NULL_TREE);
1652
1653 /* In large mode we must make sure that interrupt handlers are put into
1654 low memory as the vector table only accepts 16-bit addresses. */
1655 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl))
1656 {
1657 set_decl_section_name (decl, ".lowtext");
1658 return;
1659 }
1660
1661 default_unique_section (decl, reloc);
1662
1663 const char * prefix;
1664
1665 if ( TREE_CODE (decl) == STRING_CST
1666 || TREE_CODE (decl) == CONSTRUCTOR
1667 || TREE_CODE (decl) == INTEGER_CST
1668 || TREE_CODE (decl) == VECTOR_CST
1669 || TREE_CODE (decl) == COMPLEX_CST
1670 || (prefix = gen_prefix (decl)) == NULL
1671 )
1672 return;
1673
1674 const char * dec_name = DECL_SECTION_NAME (decl);
1675 char * name = ACONCAT ((prefix, dec_name, NULL));
1676
1677 set_decl_section_name (decl, name);
1678 }
1679
1680 /* Emit a declaration of a common symbol.
1681 If a data region is in use then put the symbol into the
1682 equivalent .bss section instead. */
1683
1684 void
1685 msp430_output_aligned_decl_common (FILE * stream,
1686 const tree decl,
1687 const char * name,
1688 unsigned HOST_WIDE_INT size,
1689 unsigned int align)
1690 {
1691 if (msp430_data_region == ANY)
1692 {
1693 fprintf (stream, COMMON_ASM_OP);
1694 assemble_name (stream, name);
1695 fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
1696 size, align / BITS_PER_UNIT);
1697 }
1698 else
1699 {
1700 section * sec;
1701
1702 if (decl)
1703 sec = msp430_select_section (decl, 0, align);
1704 else
1705 switch (msp430_data_region)
1706 {
1707 case UPPER: sec = get_named_section (NULL, ".upper.bss", 0); break;
1708 case LOWER: sec = get_named_section (NULL, ".lower.bss", 0); break;
1709 case EITHER: sec = get_named_section (NULL, ".either.bss", 0); break;
1710 default:
1711 gcc_unreachable ();
1712 }
1713 gcc_assert (sec != NULL);
1714
1715 switch_to_section (sec);
1716 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
1717 targetm.asm_out.globalize_label (stream, name);
1718 ASM_WEAKEN_LABEL (stream, name);
1719 ASM_OUTPUT_LABEL (stream, name);
1720 ASM_OUTPUT_SKIP (stream, size ? size : 1);
1721 }
1722 }
1723
1724 bool
1725 msp430_do_not_relax_short_jumps (void)
1726 {
1727 /* When placing code into "either" low or high memory we do not want the linker
1728 to grow the size of sections, which it can do if it is encounters a branch to
1729 a label that is too far away. So we tell the cbranch patterns to avoid using
1730 short jumps when there is a chance that the instructions will end up in a low
1731 section. */
1732 return
1733 msp430_code_region == EITHER
1734 || msp430_code_region == LOWER
1735 || has_attr (ATTR_EITHER, current_function_decl)
1736 || has_attr (ATTR_LOWER, current_function_decl);
1737 }
1738
1739 enum msp430_builtin
1740 {
1741 MSP430_BUILTIN_BIC_SR,
1742 MSP430_BUILTIN_BIS_SR,
1743 MSP430_BUILTIN_DELAY_CYCLES,
1744 MSP430_BUILTIN_max
1745 };
1746
1747 static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max];
1748
1749 static void
1750 msp430_init_builtins (void)
1751 {
1752 tree void_ftype_int = build_function_type_list (void_type_node, integer_type_node, NULL);
1753 tree void_ftype_longlong = build_function_type_list (void_type_node, long_long_integer_type_node, NULL);
1754
1755 msp430_builtins[MSP430_BUILTIN_BIC_SR] =
1756 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
1757 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
1758
1759 msp430_builtins[MSP430_BUILTIN_BIS_SR] =
1760 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
1761 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
1762
1763 msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
1764 add_builtin_function ( "__delay_cycles", void_ftype_longlong,
1765 MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL, NULL_TREE);
1766 }
1767
1768 static tree
1769 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
1770 {
1771 switch (code)
1772 {
1773 case MSP430_BUILTIN_BIC_SR:
1774 case MSP430_BUILTIN_BIS_SR:
1775 case MSP430_BUILTIN_DELAY_CYCLES:
1776 return msp430_builtins[code];
1777 default:
1778 return error_mark_node;
1779 }
1780 }
1781
1782 /* These constants are really register reads, which are faster than
1783 regular constants. */
1784 static int
1785 cg_magic_constant (HOST_WIDE_INT c)
1786 {
1787 switch (c)
1788 {
1789 case 0xffff:
1790 case -1:
1791 case 0:
1792 case 1:
1793 case 2:
1794 case 4:
1795 case 8:
1796 return 1;
1797 default:
1798 return 0;
1799 }
1800 }
1801
1802 static rtx
1803 msp430_expand_delay_cycles (rtx arg)
1804 {
1805 HOST_WIDE_INT i, c, n;
1806 /* extra cycles for MSP430X instructions */
1807 #define CYCX(M,X) (msp430x ? (X) : (M))
1808
1809 if (GET_CODE (arg) != CONST_INT)
1810 {
1811 error ("__delay_cycles() only takes constant arguments");
1812 return NULL_RTX;
1813 }
1814
1815 c = INTVAL (arg);
1816
1817 if (HOST_BITS_PER_WIDE_INT > 32)
1818 {
1819 if (c < 0)
1820 {
1821 error ("__delay_cycles only takes non-negative cycle counts.");
1822 return NULL_RTX;
1823 }
1824 }
1825
1826 emit_insn (gen_delay_cycles_start (arg));
1827
1828 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */
1829 if (c > 3 * 0xffff + CYCX (7, 10))
1830 {
1831 n = c;
1832 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long (x<=0xffff) loop */
1833 if (c >= 0x10000 * 7 + CYCX (14, 16))
1834 {
1835 i = 0x10000;
1836 c -= CYCX (14, 16) + 7 * 0x10000;
1837 i += c / 4;
1838 c %= 4;
1839 if ((unsigned long long) i > 0xffffffffULL)
1840 {
1841 error ("__delay_cycles is limited to 32-bit loop counts.");
1842 return NULL_RTX;
1843 }
1844 }
1845 else
1846 {
1847 i = (c - CYCX (14, 16)) / 7;
1848 c -= CYCX (14, 16) + i * 7;
1849 }
1850
1851 if (cg_magic_constant (i & 0xffff))
1852 c ++;
1853 if (cg_magic_constant ((i >> 16) & 0xffff))
1854 c ++;
1855
1856 if (msp430x)
1857 emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c)));
1858 else
1859 emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
1860 }
1861
1862 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */
1863 if (c > 12)
1864 {
1865 n = c;
1866 i = (c - CYCX (7, 10)) / 3;
1867 c -= CYCX (7, 10) + i * 3;
1868
1869 if (cg_magic_constant (i))
1870 c ++;
1871
1872 if (msp430x)
1873 emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c)));
1874 else
1875 emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c)));
1876 }
1877
1878 while (c > 1)
1879 {
1880 emit_insn (gen_delay_cycles_2 ());
1881 c -= 2;
1882 }
1883
1884 if (c)
1885 {
1886 emit_insn (gen_delay_cycles_1 ());
1887 c -= 1;
1888 }
1889
1890 emit_insn (gen_delay_cycles_end (arg));
1891
1892 return NULL_RTX;
1893 }
1894
1895 static rtx
1896 msp430_expand_builtin (tree exp,
1897 rtx target ATTRIBUTE_UNUSED,
1898 rtx subtarget ATTRIBUTE_UNUSED,
1899 machine_mode mode ATTRIBUTE_UNUSED,
1900 int ignore ATTRIBUTE_UNUSED)
1901 {
1902 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
1903 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
1904 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1905
1906 if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
1907 return msp430_expand_delay_cycles (arg1);
1908
1909 if (! msp430_is_interrupt_func ())
1910 {
1911 error ("MSP430 builtin functions only work inside interrupt handlers");
1912 return NULL_RTX;
1913 }
1914
1915 if (! REG_P (arg1) && ! CONSTANT_P (arg1))
1916 arg1 = force_reg (mode, arg1);
1917
1918 switch (fcode)
1919 {
1920 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break;
1921 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break;
1922 default:
1923 internal_error ("bad builtin code");
1924 break;
1925 }
1926 return NULL_RTX;
1927 }
1928
1929 #undef TARGET_INIT_BUILTINS
1930 #define TARGET_INIT_BUILTINS msp430_init_builtins
1931
1932 #undef TARGET_EXPAND_BUILTIN
1933 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
1934
1935 #undef TARGET_BUILTIN_DECL
1936 #define TARGET_BUILTIN_DECL msp430_builtin_decl
1937
1938 void
1939 msp430_expand_prologue (void)
1940 {
1941 int i, j;
1942 int fs;
1943 /* Always use stack_pointer_rtx instead of calling
1944 rtx_gen_REG ourselves. Code elsewhere in GCC assumes
1945 that there is a single rtx representing the stack pointer,
1946 namely stack_pointer_rtx, and uses == to recognize it. */
1947 rtx sp = stack_pointer_rtx;
1948 rtx p;
1949
1950 if (is_naked_func ())
1951 {
1952 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
1953 examines the output of the gen_prologue() function. */
1954 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
1955 return;
1956 }
1957
1958 emit_insn (gen_prologue_start_marker ());
1959
1960 if (is_critical_func ())
1961 {
1962 emit_insn (gen_push_intr_state ());
1963 emit_insn (gen_disable_interrupts ());
1964 }
1965 else if (is_reentrant_func ())
1966 emit_insn (gen_disable_interrupts ());
1967
1968 if (!cfun->machine->computed)
1969 msp430_compute_frame_info ();
1970
1971 if (flag_stack_usage_info)
1972 current_function_static_stack_size = cfun->machine->framesize;
1973
1974 if (crtl->args.pretend_args_size)
1975 {
1976 rtx note;
1977
1978 gcc_assert (crtl->args.pretend_args_size == 2);
1979
1980 p = emit_insn (gen_grow_and_swap ());
1981
1982 /* Document the stack decrement... */
1983 note = F (gen_rtx_SET (stack_pointer_rtx,
1984 gen_rtx_MINUS (Pmode, stack_pointer_rtx, GEN_INT (2))));
1985 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
1986
1987 /* ...and the establishment of a new location for the return address. */
1988 note = F (gen_rtx_SET (gen_rtx_MEM (Pmode,
1989 gen_rtx_PLUS (Pmode,
1990 stack_pointer_rtx,
1991 GEN_INT (-2))),
1992 pc_rtx));
1993 add_reg_note (p, REG_CFA_OFFSET, note);
1994 F (p);
1995 }
1996
1997 for (i = 15; i >= 4; i--)
1998 if (cfun->machine->need_to_save [i])
1999 {
2000 int seq, count;
2001 rtx note;
2002
2003 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
2004 ;
2005 count = i - seq;
2006
2007 if (msp430x)
2008 {
2009 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */
2010 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
2011 GEN_INT (count))));
2012
2013 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2014
2015 XVECEXP (note, 0, 0)
2016 = F (gen_rtx_SET (stack_pointer_rtx,
2017 gen_rtx_PLUS (Pmode,
2018 stack_pointer_rtx,
2019 GEN_INT (count * (TARGET_LARGE ? -4 : -2)))));
2020
2021 /* *sp-- = R[i-j] */
2022 /* sp+N R10
2023 ...
2024 sp R4 */
2025 for (j = 0; j < count; j ++)
2026 {
2027 rtx addr;
2028 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2029
2030 if (ofs)
2031 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2032 else
2033 addr = stack_pointer_rtx;
2034
2035 XVECEXP (note, 0, j + 1) =
2036 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2037 gen_rtx_REG (Pmode, i - j)) );
2038 }
2039
2040 add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2041 i -= count - 1;
2042 }
2043 else
2044 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2045 }
2046
2047 if (frame_pointer_needed)
2048 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2049
2050 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2051
2052 increment_stack (- fs);
2053
2054 emit_insn (gen_prologue_end_marker ());
2055 }
2056
2057 void
2058 msp430_expand_epilogue (int is_eh)
2059 {
2060 int i;
2061 int fs;
2062 int helper_n = 0;
2063
2064 if (is_naked_func ())
2065 {
2066 /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2067 examines the output of the gen_epilogue() function. */
2068 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2069 return;
2070 }
2071
2072 if (cfun->machine->need_to_save [10])
2073 {
2074 /* Check for a helper function. */
2075 helper_n = 7; /* For when the loop below never sees a match. */
2076 for (i = 9; i >= 4; i--)
2077 if (!cfun->machine->need_to_save [i])
2078 {
2079 helper_n = 10 - i;
2080 for (; i >= 4; i--)
2081 if (cfun->machine->need_to_save [i])
2082 {
2083 helper_n = 0;
2084 break;
2085 }
2086 break;
2087 }
2088 }
2089
2090 emit_insn (gen_epilogue_start_marker ());
2091
2092 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), "main") == 0)
2093 emit_insn (gen_msp430_refsym_need_exit ());
2094
2095 if (is_wakeup_func ())
2096 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2097 status register current residing on the stack. When this function
2098 executes its RETI instruction the SR will be updated with this saved
2099 value, thus ensuring that the processor is woken up from any low power
2100 state in which it may be residing. */
2101 emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2102
2103 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2104
2105 increment_stack (fs);
2106
2107 if (is_eh)
2108 {
2109 /* We need to add the right "SP" register save just after the
2110 regular ones, so that when we pop it off we're in the EH
2111 return frame, not this one. This overwrites our own return
2112 address, but we're not going to be returning anyway. */
2113 rtx r12 = gen_rtx_REG (Pmode, 12);
2114 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
2115
2116 /* R12 will hold the new SP. */
2117 i = cfun->machine->framesize_regs;
2118 emit_move_insn (r12, stack_pointer_rtx);
2119 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
2120 emit_insn (addPmode (r12, r12, GEN_INT (i)));
2121 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, i)), r12);
2122 }
2123
2124 for (i = 4; i <= 15; i++)
2125 if (cfun->machine->need_to_save [i])
2126 {
2127 int seq, count;
2128
2129 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
2130 ;
2131 count = seq - i;
2132
2133 if (msp430x)
2134 {
2135 /* Note: With TARGET_LARGE we still use
2136 POPM as POPX.A is two bytes bigger. */
2137 emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
2138 GEN_INT (count)));
2139 i += count - 1;
2140 }
2141 else if (i == 11 - helper_n
2142 && ! msp430_is_interrupt_func ()
2143 && ! is_reentrant_func ()
2144 && ! is_critical_func ()
2145 && crtl->args.pretend_args_size == 0
2146 /* Calling the helper takes as many bytes as the POP;RET sequence. */
2147 && helper_n > 1
2148 && !is_eh)
2149 {
2150 emit_insn (gen_epilogue_helper (GEN_INT (helper_n)));
2151 return;
2152 }
2153 else
2154 emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
2155 }
2156
2157 if (is_eh)
2158 {
2159 /* Also pop SP, which puts us into the EH return frame. Except
2160 that you can't "pop" sp, you have to just load it off the
2161 stack. */
2162 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode, stack_pointer_rtx));
2163 }
2164
2165 if (crtl->args.pretend_args_size)
2166 emit_insn (gen_swap_and_shrink ());
2167
2168 if (is_critical_func ())
2169 emit_insn (gen_pop_intr_state ());
2170 else if (is_reentrant_func ())
2171 emit_insn (gen_enable_interrupts ());
2172
2173 emit_jump_insn (gen_msp_return ());
2174 }
2175
2176 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in
2177 m32c_emit_eh_epilogue. */
2178 rtx
2179 msp430_eh_return_stackadj_rtx (void)
2180 {
2181 if (!cfun->machine->eh_stack_adjust)
2182 {
2183 rtx sa;
2184
2185 sa = gen_rtx_REG (Pmode, 15);
2186 cfun->machine->eh_stack_adjust = sa;
2187 }
2188 return cfun->machine->eh_stack_adjust;
2189 }
2190
2191 /* This function is called before reload, to "fix" the stack in
2192 preparation for an EH return. */
2193 void
2194 msp430_expand_eh_return (rtx eh_handler)
2195 {
2196 /* These are all Pmode */
2197 rtx ap, sa, ra, tmp;
2198
2199 ap = arg_pointer_rtx;
2200 sa = msp430_eh_return_stackadj_rtx ();
2201 ra = eh_handler;
2202
2203 tmp = ap;
2204 tmp = gen_rtx_PLUS (Pmode, ap, sa);
2205 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
2206 tmp = gen_rtx_MEM (Pmode, tmp);
2207 emit_move_insn (tmp, ra);
2208 }
2209
2210 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
2211 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2212 void
2213 msp430_init_dwarf_reg_sizes_extra (tree address)
2214 {
2215 int i;
2216 rtx addr = expand_normal (address);
2217 rtx mem = gen_rtx_MEM (BLKmode, addr);
2218
2219 if (!msp430x)
2220 return;
2221
2222 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2223 {
2224 unsigned int dnum = DWARF_FRAME_REGNUM (i);
2225 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
2226
2227 if (rnum < DWARF_FRAME_REGISTERS)
2228 {
2229 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
2230
2231 emit_move_insn (adjust_address (mem, QImode, offset),
2232 gen_int_mode (4, QImode));
2233 }
2234 }
2235 }
2236
2237 /* This is a list of MD patterns that implement fixed-count shifts. */
2238 static struct
2239 {
2240 const char *name;
2241 int count;
2242 int need_430x;
2243 rtx (*genfunc)(rtx,rtx);
2244 }
2245 const_shift_helpers[] =
2246 {
2247 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2248
2249 CSH ("slli", 1, 1, slli_1),
2250 CSH ("slll", 1, 1, slll_1),
2251 CSH ("slll", 2, 1, slll_2),
2252
2253 CSH ("srai", 1, 0, srai_1),
2254 CSH ("sral", 1, 0, sral_1),
2255 CSH ("sral", 2, 0, sral_2),
2256
2257 CSH ("srll", 1, 0, srll_1),
2258 CSH ("srll", 2, 1, srll_2x),
2259 { 0, 0, 0, 0 }
2260 #undef CSH
2261 };
2262
2263 /* The MSP430 ABI defines a number of helper functions that should be
2264 used for, for example, 32-bit shifts. This function is called to
2265 emit such a function, using the table above to optimize some
2266 cases. */
2267 void
2268 msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants)
2269 {
2270 rtx c, f;
2271 char *helper_const = NULL;
2272 int arg2 = 13;
2273 int arg1sz = 1;
2274 machine_mode arg0mode = GET_MODE (operands[0]);
2275 machine_mode arg1mode = GET_MODE (operands[1]);
2276 machine_mode arg2mode = GET_MODE (operands[2]);
2277 int have_430x = msp430x ? 1 : 0;
2278
2279 if (CONST_INT_P (operands[2]))
2280 {
2281 int i;
2282
2283 for (i=0; const_shift_helpers[i].name; i++)
2284 {
2285 if (const_shift_helpers[i].need_430x <= have_430x
2286 && strcmp (helper_name, const_shift_helpers[i].name) == 0
2287 && INTVAL (operands[2]) == const_shift_helpers[i].count)
2288 {
2289 emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1]));
2290 return;
2291 }
2292 }
2293 }
2294
2295 if (arg1mode == VOIDmode)
2296 arg1mode = arg0mode;
2297 if (arg2mode == VOIDmode)
2298 arg2mode = arg0mode;
2299
2300 if (arg1mode == SImode)
2301 {
2302 arg2 = 14;
2303 arg1sz = 2;
2304 }
2305
2306 if (const_variants
2307 && CONST_INT_P (operands[2])
2308 && INTVAL (operands[2]) >= 1
2309 && INTVAL (operands[2]) <= 15)
2310 {
2311 /* Note that the INTVAL is limited in value and length by the conditional above. */
2312 int len = strlen (helper_name) + 4;
2313 helper_const = (char *) xmalloc (len);
2314 snprintf (helper_const, len, "%s_%d", helper_name, (int) INTVAL (operands[2]));
2315 }
2316
2317 emit_move_insn (gen_rtx_REG (arg1mode, 12),
2318 operands[1]);
2319 if (!helper_const)
2320 emit_move_insn (gen_rtx_REG (arg2mode, arg2),
2321 operands[2]);
2322
2323 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12),
2324 gen_rtx_SYMBOL_REF (VOIDmode, helper_const ? helper_const : helper_name),
2325 GEN_INT (0));
2326 c = emit_call_insn (c);
2327 RTL_CONST_CALL_P (c) = 1;
2328
2329 f = 0;
2330 use_regs (&f, 12, arg1sz);
2331 if (!helper_const)
2332 use_regs (&f, arg2, 1);
2333 add_function_usage_to (c, f);
2334
2335 emit_move_insn (operands[0],
2336 gen_rtx_REG (arg0mode, 12));
2337 }
2338
2339 /* Called by cbranch<mode>4 to coerce operands into usable forms. */
2340 void
2341 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
2342 {
2343 /* constants we're looking for, not constants which are allowed. */
2344 int const_op_idx = 1;
2345
2346 if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
2347 const_op_idx = 2;
2348
2349 if (GET_CODE (operands[const_op_idx]) != REG
2350 && GET_CODE (operands[const_op_idx]) != MEM)
2351 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
2352 }
2353
2354 /* Simplify_gen_subreg() doesn't handle memory references the way we
2355 need it to below, so we use this function for when we must get a
2356 valid subreg in a "natural" state. */
2357 rtx
2358 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
2359 {
2360 rtx rv;
2361
2362 if (GET_CODE (r) == SUBREG
2363 && SUBREG_BYTE (r) == 0)
2364 {
2365 rtx ireg = SUBREG_REG (r);
2366 machine_mode imode = GET_MODE (ireg);
2367
2368 /* special case for (HI (SI (PSI ...), 0)) */
2369 if (imode == PSImode
2370 && mode == HImode
2371 && byte == 0)
2372 rv = gen_rtx_SUBREG (mode, ireg, byte);
2373 else
2374 rv = simplify_gen_subreg (mode, ireg, imode, byte);
2375 }
2376 else if (GET_CODE (r) == MEM)
2377 rv = adjust_address (r, mode, byte);
2378 else if (GET_CODE (r) == SYMBOL_REF
2379 && (byte == 0 || byte == 2)
2380 && mode == HImode)
2381 {
2382 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
2383 rv = gen_rtx_CONST (HImode, r);
2384 }
2385 else
2386 rv = simplify_gen_subreg (mode, r, omode, byte);
2387
2388 if (!rv)
2389 gcc_unreachable ();
2390
2391 return rv;
2392 }
2393
2394 /* Called by movsi_x to generate the HImode operands. */
2395 void
2396 msp430_split_movsi (rtx *operands)
2397 {
2398 rtx op00, op02, op10, op12;
2399
2400 op00 = msp430_subreg (HImode, operands[0], SImode, 0);
2401 op02 = msp430_subreg (HImode, operands[0], SImode, 2);
2402
2403 if (GET_CODE (operands[1]) == CONST
2404 || GET_CODE (operands[1]) == SYMBOL_REF)
2405 {
2406 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
2407 op10 = gen_rtx_CONST (HImode, op10);
2408 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
2409 op12 = gen_rtx_CONST (HImode, op12);
2410 }
2411 else
2412 {
2413 op10 = msp430_subreg (HImode, operands[1], SImode, 0);
2414 op12 = msp430_subreg (HImode, operands[1], SImode, 2);
2415 }
2416
2417 if (rtx_equal_p (operands[0], operands[1]))
2418 {
2419 operands[2] = op02;
2420 operands[4] = op12;
2421 operands[3] = op00;
2422 operands[5] = op10;
2423 }
2424 else if (rtx_equal_p (op00, op12)
2425 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */
2426 || (REG_P (op00) && reg_mentioned_p (op00, op10))
2427 /* Or storing (rN) into mem (rN). */
2428 || (REG_P (op10) && reg_mentioned_p (op10, op00))
2429 )
2430 {
2431 operands[2] = op02;
2432 operands[4] = op12;
2433 operands[3] = op00;
2434 operands[5] = op10;
2435 }
2436 else
2437 {
2438 operands[2] = op00;
2439 operands[4] = op10;
2440 operands[3] = op02;
2441 operands[5] = op12;
2442 }
2443 }
2444
2445 \f
2446 /* The MSPABI specifies the names of various helper functions, many of
2447 which are compatible with GCC's helpers. This table maps the GCC
2448 name to the MSPABI name. */
2449 static const struct
2450 {
2451 char const * const gcc_name;
2452 char const * const ti_name;
2453 }
2454 helper_function_name_mappings [] =
2455 {
2456 /* Floating point to/from integer conversions. */
2457 { "__truncdfsf2", "__mspabi_cvtdf" },
2458 { "__extendsfdf2", "__mspabi_cvtfd" },
2459 { "__fixdfhi", "__mspabi_fixdi" },
2460 { "__fixdfsi", "__mspabi_fixdli" },
2461 { "__fixdfdi", "__mspabi_fixdlli" },
2462 { "__fixunsdfhi", "__mspabi_fixdu" },
2463 { "__fixunsdfsi", "__mspabi_fixdul" },
2464 { "__fixunsdfdi", "__mspabi_fixdull" },
2465 { "__fixsfhi", "__mspabi_fixfi" },
2466 { "__fixsfsi", "__mspabi_fixfli" },
2467 { "__fixsfdi", "__mspabi_fixflli" },
2468 { "__fixunsfhi", "__mspabi_fixfu" },
2469 { "__fixunsfsi", "__mspabi_fixful" },
2470 { "__fixunsfdi", "__mspabi_fixfull" },
2471 { "__floathisf", "__mspabi_fltif" },
2472 { "__floatsisf", "__mspabi_fltlif" },
2473 { "__floatdisf", "__mspabi_fltllif" },
2474 { "__floathidf", "__mspabi_fltid" },
2475 { "__floatsidf", "__mspabi_fltlid" },
2476 { "__floatdidf", "__mspabi_fltllid" },
2477 { "__floatunhisf", "__mspabi_fltuf" },
2478 { "__floatunsisf", "__mspabi_fltulf" },
2479 { "__floatundisf", "__mspabi_fltullf" },
2480 { "__floatunhidf", "__mspabi_fltud" },
2481 { "__floatunsidf", "__mspabi_fltuld" },
2482 { "__floatundidf", "__mspabi_fltulld" },
2483
2484 /* Floating point comparisons. */
2485 /* GCC uses individual functions for each comparison, TI uses one
2486 compare <=> function. */
2487
2488 /* Floating point arithmatic */
2489 { "__adddf3", "__mspabi_addd" },
2490 { "__addsf3", "__mspabi_addf" },
2491 { "__divdf3", "__mspabi_divd" },
2492 { "__divsf3", "__mspabi_divf" },
2493 { "__muldf3", "__mspabi_mpyd" },
2494 { "__mulsf3", "__mspabi_mpyf" },
2495 { "__subdf3", "__mspabi_subd" },
2496 { "__subsf3", "__mspabi_subf" },
2497 /* GCC does not use helper functions for negation */
2498
2499 /* Integer multiply, divide, remainder. */
2500 { "__mulhi3", "__mspabi_mpyi" },
2501 { "__mulsi3", "__mspabi_mpyl" },
2502 { "__muldi3", "__mspabi_mpyll" },
2503 #if 0
2504 /* Clarify signed vs unsigned first. */
2505 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */
2506 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */
2507 #endif
2508
2509 { "__divhi3", "__mspabi_divi" },
2510 { "__divsi3", "__mspabi_divli" },
2511 { "__divdi3", "__mspabi_divlli" },
2512 { "__udivhi3", "__mspabi_divu" },
2513 { "__udivsi3", "__mspabi_divlu" },
2514 { "__udivdi3", "__mspabi_divllu" },
2515 { "__modhi3", "__mspabi_remi" },
2516 { "__modsi3", "__mspabi_remli" },
2517 { "__moddi3", "__mspabi_remlli" },
2518 { "__umodhi3", "__mspabi_remu" },
2519 { "__umodsi3", "__mspabi_remul" },
2520 { "__umoddi3", "__mspabi_remull" },
2521
2522 /* Bitwise operations. */
2523 /* Rotation - no rotation support yet. */
2524 /* Logical left shift - gcc already does these itself. */
2525 /* Arithmetic left shift - gcc already does these itself. */
2526 /* Arithmetic right shift - gcc already does these itself. */
2527
2528 { NULL, NULL }
2529 };
2530
2531 /* Returns true if the current MCU supports an F5xxx series
2532 hardware multiper. */
2533
2534 bool
2535 msp430_use_f5_series_hwmult (void)
2536 {
2537 static const char * cached_match = NULL;
2538 static bool cached_result;
2539
2540 if (msp430_hwmult_type == F5SERIES)
2541 return true;
2542
2543 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2544 return false;
2545
2546 if (target_mcu == cached_match)
2547 return cached_result;
2548
2549 cached_match = target_mcu;
2550
2551 if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
2552 return cached_result = true;
2553 if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
2554 return cached_result = true;
2555 if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
2556 return cached_result = true;
2557
2558 static const char * known_f5_mult_mcus [] =
2559 {
2560 "cc430f5123", "cc430f5125", "cc430f5133",
2561 "cc430f5135", "cc430f5137", "cc430f5143",
2562 "cc430f5145", "cc430f5147", "cc430f6125",
2563 "cc430f6126", "cc430f6127", "cc430f6135",
2564 "cc430f6137", "cc430f6143", "cc430f6145",
2565 "cc430f6147", "msp430bt5190", "msp430sl5438a",
2566 "msp430xgeneric"
2567 };
2568 int i;
2569
2570 for (i = ARRAY_SIZE (known_f5_mult_mcus); i--;)
2571 if (strcasecmp (target_mcu, known_f5_mult_mcus[i]) == 0)
2572 return cached_result = true;
2573
2574 return cached_result = false;
2575 }
2576
2577 /* Returns true if the current MCU has a second generation
2578 32-bit hardware multiplier. */
2579
2580 static bool
2581 use_32bit_hwmult (void)
2582 {
2583 static const char * known_32bit_mult_mcus [] =
2584 {
2585 "msp430f4783", "msp430f4793", "msp430f4784",
2586 "msp430f4794", "msp430f47126", "msp430f47127",
2587 "msp430f47163", "msp430f47173", "msp430f47183",
2588 "msp430f47193", "msp430f47166", "msp430f47176",
2589 "msp430f47186", "msp430f47196", "msp430f47167",
2590 "msp430f47177", "msp430f47187", "msp430f47197"
2591 };
2592 static const char * cached_match = NULL;
2593 static bool cached_result;
2594 int i;
2595
2596 if (msp430_hwmult_type == LARGE)
2597 return true;
2598
2599 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2600 return false;
2601
2602 if (target_mcu == cached_match)
2603 return cached_result;
2604
2605 cached_match = target_mcu;
2606 for (i = ARRAY_SIZE (known_32bit_mult_mcus); i--;)
2607 if (strcasecmp (target_mcu, known_32bit_mult_mcus[i]) == 0)
2608 return cached_result = true;
2609
2610 return cached_result = false;
2611 }
2612
2613 /* Returns true if the current MCU does not have a
2614 hardware multiplier of any kind. */
2615
2616 static bool
2617 msp430_no_hwmult (void)
2618 {
2619 static const char * known_nomult_mcus [] =
2620 {
2621 "msp430c091", "msp430c092", "msp430c111",
2622 "msp430c1111", "msp430c112", "msp430c1121",
2623 "msp430c1331", "msp430c1351", "msp430c311s",
2624 "msp430c312", "msp430c313", "msp430c314",
2625 "msp430c315", "msp430c323", "msp430c325",
2626 "msp430c412", "msp430c413", "msp430e112",
2627 "msp430e313", "msp430e315", "msp430e325",
2628 "msp430f110", "msp430f1101", "msp430f1101a",
2629 "msp430f1111", "msp430f1111a", "msp430f112",
2630 "msp430f1121", "msp430f1121a", "msp430f1122",
2631 "msp430f1132", "msp430f122", "msp430f1222",
2632 "msp430f123", "msp430f1232", "msp430f133",
2633 "msp430f135", "msp430f155", "msp430f156",
2634 "msp430f157", "msp430f2001", "msp430f2002",
2635 "msp430f2003", "msp430f2011", "msp430f2012",
2636 "msp430f2013", "msp430f2101", "msp430f2111",
2637 "msp430f2112", "msp430f2121", "msp430f2122",
2638 "msp430f2131", "msp430f2132", "msp430f2232",
2639 "msp430f2234", "msp430f2252", "msp430f2254",
2640 "msp430f2272", "msp430f2274", "msp430f412",
2641 "msp430f413", "msp430f4132", "msp430f415",
2642 "msp430f4152", "msp430f417", "msp430f4250",
2643 "msp430f4260", "msp430f4270", "msp430f435",
2644 "msp430f4351", "msp430f436", "msp430f4361",
2645 "msp430f437", "msp430f4371", "msp430f438",
2646 "msp430f439", "msp430f477", "msp430f478",
2647 "msp430f479", "msp430fe423", "msp430fe4232",
2648 "msp430fe423a", "msp430fe4242", "msp430fe425",
2649 "msp430fe4252", "msp430fe425a", "msp430fe427",
2650 "msp430fe4272", "msp430fe427a", "msp430fg4250",
2651 "msp430fg4260", "msp430fg4270", "msp430fg437",
2652 "msp430fg438", "msp430fg439", "msp430fg477",
2653 "msp430fg478", "msp430fg479", "msp430fr2032",
2654 "msp430fr2033", "msp430fr4131", "msp430fr4132",
2655 "msp430fr4133", "msp430fw423", "msp430fw425",
2656 "msp430fw427", "msp430fw428", "msp430fw429",
2657 "msp430g2001", "msp430g2101", "msp430g2102",
2658 "msp430g2111", "msp430g2112", "msp430g2113",
2659 "msp430g2121", "msp430g2131", "msp430g2132",
2660 "msp430g2152", "msp430g2153", "msp430g2201",
2661 "msp430g2202", "msp430g2203", "msp430g2210",
2662 "msp430g2211", "msp430g2212", "msp430g2213",
2663 "msp430g2221", "msp430g2230", "msp430g2231",
2664 "msp430g2232", "msp430g2233", "msp430g2252",
2665 "msp430g2253", "msp430g2302", "msp430g2303",
2666 "msp430g2312", "msp430g2313", "msp430g2332",
2667 "msp430g2333", "msp430g2352", "msp430g2353",
2668 "msp430g2402", "msp430g2403", "msp430g2412",
2669 "msp430g2413", "msp430g2432", "msp430g2433",
2670 "msp430g2444", "msp430g2452", "msp430g2453",
2671 "msp430g2513", "msp430g2533", "msp430g2544",
2672 "msp430g2553", "msp430g2744", "msp430g2755",
2673 "msp430g2855", "msp430g2955", "msp430l092",
2674 "msp430p112", "msp430p313", "msp430p315",
2675 "msp430p315s", "msp430p325", "msp430tch5e"
2676 };
2677 static const char * cached_match = NULL;
2678 static bool cached_result;
2679 int i;
2680
2681 if (msp430_hwmult_type == NONE)
2682 return true;
2683
2684 if (target_mcu == NULL || msp430_hwmult_type != AUTO)
2685 return false;
2686
2687 if (target_mcu == cached_match)
2688 return cached_result;
2689
2690 cached_match = target_mcu;
2691 for (i = ARRAY_SIZE (known_nomult_mcus); i--;)
2692 if (strcasecmp (target_mcu, known_nomult_mcus[i]) == 0)
2693 return cached_result = true;
2694
2695 return cached_result = false;
2696 }
2697
2698 /* This function does the same as the default, but it will replace GCC
2699 function names with the MSPABI-specified ones. */
2700
2701 void
2702 msp430_output_labelref (FILE *file, const char *name)
2703 {
2704 int i;
2705
2706 for (i = 0; helper_function_name_mappings [i].gcc_name; i++)
2707 if (strcmp (helper_function_name_mappings [i].gcc_name, name) == 0)
2708 {
2709 name = helper_function_name_mappings [i].ti_name;
2710 break;
2711 }
2712
2713 /* If we have been given a specific MCU name then we may be
2714 able to make use of its hardware multiply capabilities. */
2715 if (msp430_hwmult_type != NONE)
2716 {
2717 if (strcmp ("__mspabi_mpyi", name) == 0)
2718 {
2719 if (msp430_use_f5_series_hwmult ())
2720 name = "__mulhi2_f5";
2721 else if (! msp430_no_hwmult ())
2722 name = "__mulhi2";
2723 }
2724 else if (strcmp ("__mspabi_mpyl", name) == 0)
2725 {
2726 if (msp430_use_f5_series_hwmult ())
2727 name = "__mulsi2_f5";
2728 else if (use_32bit_hwmult ())
2729 name = "__mulsi2_hw32";
2730 else if (! msp430_no_hwmult ())
2731 name = "__mulsi2";
2732 }
2733 }
2734
2735 fputs (name, file);
2736 }
2737
2738 /* Common code for msp430_print_operand... */
2739
2740 static void
2741 msp430_print_operand_raw (FILE * file, rtx op)
2742 {
2743 HOST_WIDE_INT i;
2744
2745 switch (GET_CODE (op))
2746 {
2747 case REG:
2748 fprintf (file, "%s", reg_names [REGNO (op)]);
2749 break;
2750
2751 case CONST_INT:
2752 i = INTVAL (op);
2753 if (TARGET_ASM_HEX)
2754 fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
2755 else
2756 fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
2757 break;
2758
2759 case CONST:
2760 case PLUS:
2761 case MINUS:
2762 case SYMBOL_REF:
2763 case LABEL_REF:
2764 output_addr_const (file, op);
2765 break;
2766
2767 default:
2768 print_rtl (file, op);
2769 break;
2770 }
2771 }
2772
2773 #undef TARGET_PRINT_OPERAND_ADDRESS
2774 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr
2775
2776 /* Output to stdio stream FILE the assembler syntax for an
2777 instruction operand that is a memory reference whose address
2778 is ADDR. */
2779
2780 static void
2781 msp430_print_operand_addr (FILE * file, rtx addr)
2782 {
2783 switch (GET_CODE (addr))
2784 {
2785 case PLUS:
2786 msp430_print_operand_raw (file, XEXP (addr, 1));
2787 gcc_assert (REG_P (XEXP (addr, 0)));
2788 fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]);
2789 return;
2790
2791 case REG:
2792 fprintf (file, "@");
2793 break;
2794
2795 case CONST:
2796 case CONST_INT:
2797 case SYMBOL_REF:
2798 case LABEL_REF:
2799 fprintf (file, "&");
2800 break;
2801
2802 default:
2803 break;
2804 }
2805
2806 msp430_print_operand_raw (file, addr);
2807 }
2808
2809 #undef TARGET_PRINT_OPERAND
2810 #define TARGET_PRINT_OPERAND msp430_print_operand
2811
2812 /* A low 16-bits of int/lower of register pair
2813 B high 16-bits of int/higher of register pair
2814 C bits 32-47 of a 64-bit value/reg 3 of a DImode value
2815 D bits 48-63 of a 64-bit value/reg 4 of a DImode value
2816 H like %B (for backwards compatibility)
2817 I inverse of value
2818 J an integer without a # prefix
2819 L like %A (for backwards compatibility)
2820 O offset of the top of the stack
2821 Q like X but generates an A postfix
2822 R inverse of condition code, unsigned.
2823 X X instruction postfix in large mode
2824 Y value - 4
2825 Z value - 1
2826 b .B or .W or .A, depending upon the mode
2827 p bit position
2828 r inverse of condition code
2829 x like X but only for pointers. */
2830
2831 static void
2832 msp430_print_operand (FILE * file, rtx op, int letter)
2833 {
2834 rtx addr;
2835
2836 /* We can't use c, n, a, or l. */
2837 switch (letter)
2838 {
2839 case 'Z':
2840 gcc_assert (CONST_INT_P (op));
2841 /* Print the constant value, less one. */
2842 fprintf (file, "#%ld", INTVAL (op) - 1);
2843 return;
2844 case 'Y':
2845 gcc_assert (CONST_INT_P (op));
2846 /* Print the constant value, less four. */
2847 fprintf (file, "#%ld", INTVAL (op) - 4);
2848 return;
2849 case 'I':
2850 if (GET_CODE (op) == CONST_INT)
2851 {
2852 /* Inverse of constants */
2853 int i = INTVAL (op);
2854 fprintf (file, "%d", ~i);
2855 return;
2856 }
2857 op = XEXP (op, 0);
2858 break;
2859 case 'r': /* Conditional jump where the condition is reversed. */
2860 switch (GET_CODE (op))
2861 {
2862 case EQ: fprintf (file, "NE"); break;
2863 case NE: fprintf (file, "EQ"); break;
2864 case GEU: fprintf (file, "LO"); break;
2865 case LTU: fprintf (file, "HS"); break;
2866 case GE: fprintf (file, "L"); break;
2867 case LT: fprintf (file, "GE"); break;
2868 /* Assume these have reversed operands. */
2869 case GTU: fprintf (file, "HS"); break;
2870 case LEU: fprintf (file, "LO"); break;
2871 case GT: fprintf (file, "GE"); break;
2872 case LE: fprintf (file, "L"); break;
2873 default:
2874 msp430_print_operand_raw (file, op);
2875 break;
2876 }
2877 return;
2878 case 'R': /* Conditional jump where the operands are reversed. */
2879 switch (GET_CODE (op))
2880 {
2881 case GTU: fprintf (file, "LO"); break;
2882 case LEU: fprintf (file, "HS"); break;
2883 case GT: fprintf (file, "L"); break;
2884 case LE: fprintf (file, "GE"); break;
2885 default:
2886 msp430_print_operand_raw (file, op);
2887 break;
2888 }
2889 return;
2890 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
2891 gcc_assert (CONST_INT_P (op));
2892 fprintf (file, "#%d", 1 << INTVAL (op));
2893 return;
2894 case 'b':
2895 switch (GET_MODE (op))
2896 {
2897 case QImode: fprintf (file, ".B"); return;
2898 case HImode: fprintf (file, ".W"); return;
2899 case PSImode: fprintf (file, ".A"); return;
2900 case SImode: fprintf (file, ".A"); return;
2901 default:
2902 return;
2903 }
2904 case 'A':
2905 case 'L': /* Low half. */
2906 switch (GET_CODE (op))
2907 {
2908 case MEM:
2909 op = adjust_address (op, Pmode, 0);
2910 break;
2911 case REG:
2912 break;
2913 case CONST_INT:
2914 op = GEN_INT (INTVAL (op) & 0xffff);
2915 letter = 0;
2916 break;
2917 default:
2918 /* If you get here, figure out a test case :-) */
2919 gcc_unreachable ();
2920 }
2921 break;
2922 case 'B':
2923 case 'H': /* high half */
2924 switch (GET_CODE (op))
2925 {
2926 case MEM:
2927 op = adjust_address (op, Pmode, 2);
2928 break;
2929 case REG:
2930 op = gen_rtx_REG (Pmode, REGNO (op) + 1);
2931 break;
2932 case CONST_INT:
2933 op = GEN_INT (INTVAL (op) >> 16);
2934 letter = 0;
2935 break;
2936 default:
2937 /* If you get here, figure out a test case :-) */
2938 gcc_unreachable ();
2939 }
2940 break;
2941 case 'C':
2942 switch (GET_CODE (op))
2943 {
2944 case MEM:
2945 op = adjust_address (op, Pmode, 3);
2946 break;
2947 case REG:
2948 op = gen_rtx_REG (Pmode, REGNO (op) + 2);
2949 break;
2950 case CONST_INT:
2951 op = GEN_INT ((long long) INTVAL (op) >> 32);
2952 letter = 0;
2953 break;
2954 default:
2955 /* If you get here, figure out a test case :-) */
2956 gcc_unreachable ();
2957 }
2958 break;
2959 case 'D':
2960 switch (GET_CODE (op))
2961 {
2962 case MEM:
2963 op = adjust_address (op, Pmode, 4);
2964 break;
2965 case REG:
2966 op = gen_rtx_REG (Pmode, REGNO (op) + 3);
2967 break;
2968 case CONST_INT:
2969 op = GEN_INT ((long long) INTVAL (op) >> 48);
2970 letter = 0;
2971 break;
2972 default:
2973 /* If you get here, figure out a test case :-) */
2974 gcc_unreachable ();
2975 }
2976 break;
2977
2978 case 'X':
2979 /* This is used to turn, for example, an ADD opcode into an ADDX
2980 opcode when we're using 20-bit addresses. */
2981 if (TARGET_LARGE || GET_MODE (op) == PSImode)
2982 fprintf (file, "X");
2983 /* We don't care which operand we use, but we want 'X' in the MD
2984 file, so we do it this way. */
2985 return;
2986
2987 case 'x':
2988 /* Similarly, but only for PSImodes. BIC, for example, needs this. */
2989 if (GET_MODE (op) == PSImode)
2990 fprintf (file, "X");
2991 return;
2992
2993 case 'Q':
2994 /* Likewise, for BR -> BRA. */
2995 if (TARGET_LARGE)
2996 fprintf (file, "A");
2997 return;
2998
2999 case 'O':
3000 /* Computes the offset to the top of the stack for the current frame.
3001 This has to be done here rather than in, say, msp430_expand_builtin()
3002 because builtins are expanded before the frame layout is determined. */
3003 fprintf (file, "%d",
3004 msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM)
3005 - (TARGET_LARGE ? 4 : 2));
3006 return;
3007
3008 case 'J':
3009 gcc_assert (GET_CODE (op) == CONST_INT);
3010 case 0:
3011 break;
3012 default:
3013 output_operand_lossage ("invalid operand prefix");
3014 return;
3015 }
3016
3017 switch (GET_CODE (op))
3018 {
3019 case REG:
3020 msp430_print_operand_raw (file, op);
3021 break;
3022
3023 case MEM:
3024 addr = XEXP (op, 0);
3025 msp430_print_operand_addr (file, addr);
3026 break;
3027
3028 case CONST:
3029 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
3030 {
3031 op = XEXP (op, 0);
3032 switch (INTVAL (XEXP (op, 2)))
3033 {
3034 case 0:
3035 fprintf (file, "#lo (");
3036 msp430_print_operand_raw (file, XEXP (op, 0));
3037 fprintf (file, ")");
3038 break;
3039
3040 case 16:
3041 fprintf (file, "#hi (");
3042 msp430_print_operand_raw (file, XEXP (op, 0));
3043 fprintf (file, ")");
3044 break;
3045
3046 default:
3047 output_operand_lossage ("invalid zero extract");
3048 break;
3049 }
3050 break;
3051 }
3052 /* Fall through. */
3053 case CONST_INT:
3054 case SYMBOL_REF:
3055 case LABEL_REF:
3056 if (letter == 0)
3057 fprintf (file, "#");
3058 msp430_print_operand_raw (file, op);
3059 break;
3060
3061 case EQ: fprintf (file, "EQ"); break;
3062 case NE: fprintf (file, "NE"); break;
3063 case GEU: fprintf (file, "HS"); break;
3064 case LTU: fprintf (file, "LO"); break;
3065 case GE: fprintf (file, "GE"); break;
3066 case LT: fprintf (file, "L"); break;
3067
3068 default:
3069 print_rtl (file, op);
3070 break;
3071 }
3072 }
3073
3074 \f
3075 /* Frame stuff. */
3076
3077 rtx
3078 msp430_return_addr_rtx (int count)
3079 {
3080 int ra_size;
3081 if (count)
3082 return NULL_RTX;
3083
3084 ra_size = TARGET_LARGE ? 4 : 2;
3085 if (crtl->args.pretend_args_size)
3086 ra_size += 2;
3087
3088 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size)));
3089 }
3090
3091 rtx
3092 msp430_incoming_return_addr_rtx (void)
3093 {
3094 return gen_rtx_MEM (Pmode, stack_pointer_rtx);
3095 }
3096 \f
3097 /* Instruction generation stuff. */
3098
3099 /* Generate a sequence of instructions to sign-extend an HI
3100 value into an SI value. Handles the tricky case where
3101 we are overwriting the destination. */
3102
3103 const char *
3104 msp430x_extendhisi (rtx * operands)
3105 {
3106 if (REGNO (operands[0]) == REGNO (operands[1]))
3107 /* Low word of dest == source word. */
3108 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */
3109
3110 if (! msp430x)
3111 /* Note: This sequence is approximately the same length as invoking a helper
3112 function to perform the sign-extension, as in:
3113
3114 MOV.W %1, %L0
3115 MOV.W %1, r12
3116 CALL __mspabi_srai_15
3117 MOV.W r12, %H0
3118
3119 but this version does not involve any function calls or using argument
3120 registers, so it reduces register pressure. */
3121 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */
3122
3123 if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
3124 /* High word of dest == source word. */
3125 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
3126
3127 /* No overlap between dest and source. */
3128 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */
3129 }
3130
3131 /* Likewise for logical right shifts. */
3132 const char *
3133 msp430x_logical_shift_right (rtx amount)
3134 {
3135 /* The MSP430X's logical right shift instruction - RRUM - does
3136 not use an extension word, so we cannot encode a repeat count.
3137 Try various alternatives to work around this. If the count
3138 is in a register we are stuck, hence the assert. */
3139 gcc_assert (CONST_INT_P (amount));
3140
3141 if (INTVAL (amount) <= 0
3142 || INTVAL (amount) >= 16)
3143 return "# nop logical shift.";
3144
3145 if (INTVAL (amount) > 0
3146 && INTVAL (amount) < 5)
3147 return "rrum.w\t%2, %0"; /* Two bytes. */
3148
3149 if (INTVAL (amount) > 4
3150 && INTVAL (amount) < 9)
3151 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */
3152
3153 /* First we logically shift right by one. Now we know
3154 that the top bit is zero and we can use the arithmetic
3155 right shift instruction to perform the rest of the shift. */
3156 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */
3157 }
3158 \f
3159 struct gcc_target targetm = TARGET_INITIALIZER;
3160
3161 #include "gt-msp430.h"