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