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