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