1 /* Subroutines used for code generation on TI MSP430 processors.
2    Copyright (C) 2012-2020 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 #define IN_TARGET_CODE 1
22 
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "gimple-expr.h"
33 #include "df.h"
34 #include "memmodel.h"
35 #include "tm_p.h"
36 #include "regs.h"
37 #include "emit-rtl.h"
38 #include "varasm.h"
39 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
42 #include "calls.h"
43 #include "output.h"
44 #include "explow.h"
45 #include "expr.h"
46 #include "langhooks.h"
47 #include "builtins.h"
48 #include "intl.h"
49 #include "msp430-devices.h"
50 #include "incpath.h"
51 #include "prefix.h"
52 
53 /* This file should be included last.  */
54 #include "target-def.h"
55 
56 
57 static void msp430_compute_frame_info (void);
58 static bool use_32bit_hwmult (void);
59 
60 
61 
62 /* Run-time Target Specification.  */
63 
64 bool msp430x = true;
65 
66 struct GTY(()) machine_function
67 {
68   /* If set, the rest of the fields have been computed.  */
69   int computed;
70   /* Which registers need to be saved in the pro/epilogue.  */
71   int need_to_save[FIRST_PSEUDO_REGISTER];
72 
73   /* These fields describe the frame layout...  */
74   /* arg pointer */
75   /* 2/4 bytes for saved PC */
76   int framesize_regs;
77   /* frame pointer */
78   int framesize_locals;
79   int framesize_outgoing;
80   /* stack pointer */
81   int framesize;
82 
83   /* How much we adjust the stack when returning from an exception
84      handler.  */
85   rtx eh_stack_adjust;
86 };
87 
88 /* This is our init_machine_status, as set in
89    msp430_option_override.  */
90 static struct machine_function *
msp430_init_machine_status(void)91 msp430_init_machine_status (void)
92 {
93   struct machine_function *m;
94 
95   m = ggc_cleared_alloc<machine_function> ();
96 
97   return m;
98 }
99 
100 #undef  TARGET_OPTION_OVERRIDE
101 #define TARGET_OPTION_OVERRIDE		msp430_option_override
102 
103 /* Generate a C preprocessor symbol based upon the MCU selected by the user.
104    If a specific MCU has not been selected then return a generic symbol
105    instead.  */
106 
107 const char *
msp430_mcu_name(void)108 msp430_mcu_name (void)
109 {
110   if (target_mcu)
111     {
112       msp430_extract_mcu_data (target_mcu);
113       unsigned int i;
114       unsigned int start_upper;
115       unsigned int end_upper;
116       static char mcu_name[64];
117 
118       /* The 'i' in the device name symbol for msp430i* devices must be lower
119 	 case, to match the expected symbol in msp430.h.  */
120       if (strncmp (target_mcu, "msp430i", 7) == 0)
121 	{
122 	  snprintf (mcu_name, sizeof (mcu_name) - 1, "__MSP430i%s__",
123 		    target_mcu + 7);
124 	  start_upper = 9;
125 	}
126       else
127 	{
128 	  snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu);
129 	  start_upper = 2;
130 	}
131       end_upper = strlen (mcu_name) - 2;
132       for (i = start_upper; i < end_upper; i++)
133 	mcu_name[i] = TOUPPER (mcu_name[i]);
134       return mcu_name;
135     }
136 
137   return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
138 }
139 
140 static const char *
hwmult_name(unsigned int val)141 hwmult_name (unsigned int val)
142 {
143   switch (val)
144     {
145     case 0: return "none";
146     case 1: return "16-bit";
147     case 2: return "16-bit";
148     case 4: return "32-bit";
149     case 8: return "32-bit (5xx)";
150     default: gcc_unreachable ();
151     }
152 }
153 
154 static void
msp430_option_override(void)155 msp430_option_override (void)
156 {
157   /* The MSP430 architecture can safely dereference a NULL pointer.  In fact,
158      there are memory mapped registers there.  */
159   flag_delete_null_pointer_checks = 0;
160 
161   init_machine_status = msp430_init_machine_status;
162 
163   if (target_cpu)
164     {
165       /* gcc/common/config/msp430-common.c will have
166 	 already canonicalised the string in target_cpu.  */
167       if (strcasecmp (target_cpu, "msp430x") == 0)
168 	msp430x = true;
169       else /* target_cpu == "msp430" - already handled by the front end.  */
170 	msp430x = false;
171     }
172 
173   if (target_mcu)
174     {
175       msp430_extract_mcu_data (target_mcu);
176 
177       if (extracted_mcu_data.name != NULL)
178 	{
179 	  bool xisa = extracted_mcu_data.revision >= 1;
180 
181 	  if (msp430_warn_mcu)
182 	    {
183 	      if (target_cpu && msp430x != xisa)
184 		warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
185 			 "is set to %s",
186 			 target_mcu, xisa ? "430X" : "430",
187 			 msp430x ? "430X" : "430");
188 
189 	      if (extracted_mcu_data.hwmpy == 0
190 		  && msp430_hwmult_type != MSP430_HWMULT_AUTO
191 		  && msp430_hwmult_type != MSP430_HWMULT_NONE)
192 		warning (0, "MCU %qs does not have hardware multiply "
193 			 "support, but %<-mhwmult%> is set to %s",
194 			 target_mcu,
195 			 msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit"
196 			 : msp430_hwmult_type == MSP430_HWMULT_LARGE
197 			 ? "32-bit" : "f5series");
198 	      else if (msp430_hwmult_type == MSP430_HWMULT_SMALL
199 		       && extracted_mcu_data.hwmpy != 1
200 		       && extracted_mcu_data.hwmpy != 2)
201 		warning (0, "MCU %qs supports %s hardware multiply, "
202 			 "but %<-mhwmult%> is set to 16-bit",
203 			 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
204 	      else if (msp430_hwmult_type == MSP430_HWMULT_LARGE
205 		       && extracted_mcu_data.hwmpy != 4)
206 		warning (0, "MCU %qs supports %s hardware multiply, "
207 			 "but %<-mhwmult%> is set to 32-bit",
208 			 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
209 	      else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES
210 		       && extracted_mcu_data.hwmpy != 8)
211 		warning (0, "MCU %qs supports %s hardware multiply, "
212 			 "but %<-mhwmult%> is set to f5series",
213 			 target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
214 	    }
215 	  msp430x = xisa;
216 	}
217       else
218 	{
219 	  if (msp430_hwmult_type == MSP430_HWMULT_AUTO)
220 	    {
221 	      if (msp430_warn_mcu)
222 		{
223 		  if (target_cpu == NULL)
224 		    warning (0,
225 			     "Unrecognized MCU name %qs, assuming that it is "
226 			     "just a MSP430 with no hardware multiply.\n"
227 			     "Use the %<-mcpu%> and %<-mhwmult%> options to "
228 			     "set these explicitly.",
229 			     target_mcu);
230 		  else
231 		    warning (0,
232 			     "Unrecognized MCU name %qs, assuming that it "
233 			     "has no hardware multiply.\nUse the %<-mhwmult%> "
234 			     "option to set this explicitly.",
235 			     target_mcu);
236 		}
237 
238 	      msp430_hwmult_type = MSP430_HWMULT_NONE;
239 	    }
240 	  else if (target_cpu == NULL)
241 	    {
242 	      if (msp430_warn_mcu)
243 		warning (0,
244 			 "Unrecognized MCU name %qs, assuming that it just "
245 			 "supports the MSP430 ISA.\nUse the %<-mcpu%> option "
246 			 "to set the ISA explicitly.",
247 			 target_mcu);
248 
249 	      msp430x = false;
250 	    }
251 	  else if (msp430_warn_mcu)
252 	    warning (0, "Unrecognized MCU name %qs.", target_mcu);
253 	}
254     }
255 
256   /* The F5 series are all able to support the 430X ISA.  */
257   if (target_cpu == NULL && target_mcu == NULL
258       && msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
259     msp430x = true;
260 
261   if (TARGET_LARGE && !msp430x)
262     error ("%<-mlarge%> requires a 430X-compatible %<-mmcu=%>");
263 
264   if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_EITHER)
265     error ("%<-mcode-region=either%> requires the large memory model "
266 	   "(%<-mlarge%>)");
267   else if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_UPPER)
268     error ("%<-mcode-region=upper%> requires the large memory model "
269 	   "(%<-mlarge%>)");
270 
271   if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_EITHER)
272     error ("%<-mdata-region=either%> requires the large memory model "
273 	   "(%<-mlarge%>)");
274   else if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_UPPER)
275     error ("%<-mdata-region=upper%> requires the large memory model "
276 	   "(%<-mlarge%>)");
277 
278   if (flag_exceptions || flag_non_call_exceptions
279       || flag_unwind_tables || flag_asynchronous_unwind_tables)
280     flag_omit_frame_pointer = false;
281   else
282     flag_omit_frame_pointer = true;
283 
284   /* This is a hack to work around a problem with the newlib build
285      mechanism.  Newlib always appends CFLAGS to the end of the GCC
286      command line and always sets -O2 in CFLAGS.  Thus it is not
287      possible to build newlib with -Os enabled.  Until now...  */
288   if (TARGET_OPT_SPACE && optimize < 3)
289     optimize_size = 1;
290 
291 #if !DEFAULT_USE_CXA_ATEXIT
292   /* For some configurations, we use atexit () instead of __cxa_atexit () by
293      default to save on code size and remove the declaration of __dso_handle
294      from the CRT library.
295      Configuring GCC with --enable-__cxa-atexit re-enables it by defining
296      DEFAULT_USE_CXA_ATEXIT to 1.  */
297   if (flag_use_cxa_atexit)
298     error ("%<-fuse-cxa-atexit%> is not supported for msp430-elf");
299 #endif
300 
301 #ifndef HAVE_NEWLIB_NANO_FORMATTED_IO
302   if (TARGET_TINY_PRINTF)
303     error ("GCC must be configured with %<--enable-newlib-nano-formatted-io%> "
304 	   "to use %<-mtiny-printf%>");
305 #endif
306 }
307 
308 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
309 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p
310 
311 static bool
msp430_scalar_mode_supported_p(scalar_mode m)312 msp430_scalar_mode_supported_p (scalar_mode m)
313 {
314   if (m == PSImode && msp430x)
315     return true;
316 #if 0
317   if (m == TImode)
318     return true;
319 #endif
320   return default_scalar_mode_supported_p (m);
321 }
322 
323 
324 
325 /* Storage Layout */
326 
327 #undef  TARGET_MS_BITFIELD_LAYOUT_P
328 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p
329 
330 bool
msp430_ms_bitfield_layout_p(const_tree record_type ATTRIBUTE_UNUSED)331 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED)
332 {
333   return false;
334 }
335 
336 
337 
338 /* Register Usage */
339 
340 #undef TARGET_HARD_REGNO_NREGS
341 #define TARGET_HARD_REGNO_NREGS msp430_hard_regno_nregs
342 
343 static unsigned int
msp430_hard_regno_nregs(unsigned int,machine_mode mode)344 msp430_hard_regno_nregs (unsigned int, machine_mode mode)
345 {
346   if (mode == PSImode && msp430x)
347     return 1;
348   if (mode == CPSImode && msp430x)
349     return 2;
350   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
351 	  / UNITS_PER_WORD);
352 }
353 
354 /* subreg_get_info correctly handles PSImode registers, so defining
355    HARD_REGNO_NREGS_HAS_PADDING and HARD_REGNO_NREGS_WITH_PADDING
356    has no effect.  */
357 
358 #undef TARGET_HARD_REGNO_MODE_OK
359 #define TARGET_HARD_REGNO_MODE_OK msp430_hard_regno_mode_ok
360 
361 static bool
msp430_hard_regno_mode_ok(unsigned int regno,machine_mode mode)362 msp430_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
363 {
364   return regno <= (ARG_POINTER_REGNUM
365 		   - (unsigned int) msp430_hard_regno_nregs (regno, mode));
366 }
367 
368 #undef TARGET_MODES_TIEABLE_P
369 #define TARGET_MODES_TIEABLE_P msp430_modes_tieable_p
370 
371 static bool
msp430_modes_tieable_p(machine_mode mode1,machine_mode mode2)372 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2)
373 {
374   if ((mode1 == PSImode || mode2 == SImode)
375       || (mode1 == SImode || mode2 == PSImode))
376     return false;
377 
378   return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
379 	   || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
380 	  == (GET_MODE_CLASS (mode2) == MODE_FLOAT
381 	      || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
382 }
383 
384 #undef  TARGET_FRAME_POINTER_REQUIRED
385 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required
386 
387 static bool
msp430_frame_pointer_required(void)388 msp430_frame_pointer_required (void)
389 {
390   return false;
391 }
392 
393 #undef  TARGET_CAN_ELIMINATE
394 #define TARGET_CAN_ELIMINATE		msp430_can_eliminate
395 
396 static bool
msp430_can_eliminate(const int from_reg ATTRIBUTE_UNUSED,const int to_reg ATTRIBUTE_UNUSED)397 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED,
398 		      const int to_reg ATTRIBUTE_UNUSED)
399 {
400   return true;
401 }
402 
403 /* Implements INITIAL_ELIMINATION_OFFSET.  */
404 int
msp430_initial_elimination_offset(int from,int to)405 msp430_initial_elimination_offset (int from, int to)
406 {
407   int rv = 0; /* As if arg to arg.  */
408 
409   msp430_compute_frame_info ();
410 
411   switch (to)
412     {
413     case STACK_POINTER_REGNUM:
414       rv += cfun->machine->framesize_outgoing;
415       rv += cfun->machine->framesize_locals;
416       /* Fall through.  */
417     case FRAME_POINTER_REGNUM:
418       rv += cfun->machine->framesize_regs;
419       /* Allow for the saved return address.  */
420       rv += (TARGET_LARGE ? 4 : 2);
421       /* NB/ No need to allow for crtl->args.pretend_args_size.
422 	 GCC does that for us.  */
423       break;
424     default:
425       gcc_unreachable ();
426     }
427 
428   switch (from)
429     {
430     case FRAME_POINTER_REGNUM:
431       /* Allow for the fall through above.  */
432       rv -= (TARGET_LARGE ? 4 : 2);
433       rv -= cfun->machine->framesize_regs;
434     case ARG_POINTER_REGNUM:
435       break;
436     default:
437       gcc_unreachable ();
438     }
439 
440   return rv;
441 }
442 
443 /* Named Address Space support */
444 
445 
446 /* Return the appropriate mode for a named address pointer.  */
447 #undef  TARGET_ADDR_SPACE_POINTER_MODE
448 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode
449 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
450 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode
451 
452 static scalar_int_mode
msp430_addr_space_pointer_mode(addr_space_t addrspace)453 msp430_addr_space_pointer_mode (addr_space_t addrspace)
454 {
455   switch (addrspace)
456     {
457     default:
458     case ADDR_SPACE_GENERIC:
459       return Pmode;
460     case ADDR_SPACE_NEAR:
461       return HImode;
462     case ADDR_SPACE_FAR:
463       return PSImode;
464     }
465 }
466 
467 /* Function pointers are stored in unwind_word sized
468    variables, so make sure that unwind_word is big enough.  */
469 #undef  TARGET_UNWIND_WORD_MODE
470 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode
471 
472 static scalar_int_mode
msp430_unwind_word_mode(void)473 msp430_unwind_word_mode (void)
474 {
475   /* This needs to match msp430_init_dwarf_reg_sizes_extra (below).  */
476   return msp430x ? PSImode : HImode;
477 }
478 
479 /* Determine if one named address space is a subset of another.  */
480 #undef  TARGET_ADDR_SPACE_SUBSET_P
481 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p
482 static bool
msp430_addr_space_subset_p(addr_space_t subset,addr_space_t superset)483 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
484 {
485   if (subset == superset)
486     return true;
487   else
488     return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR);
489 }
490 
491 #undef  TARGET_ADDR_SPACE_CONVERT
492 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert
493 /* Convert from one address space to another.  */
494 static rtx
msp430_addr_space_convert(rtx op,tree from_type,tree to_type)495 msp430_addr_space_convert (rtx op, tree from_type, tree to_type)
496 {
497   addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
498   addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
499   rtx result;
500 
501   if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR)
502     {
503       /* This is unpredictable, as we're truncating off usable address
504 	 bits.  */
505 
506       if (CONSTANT_P (op))
507 	return gen_rtx_CONST (HImode, op);
508 
509       result = gen_reg_rtx (HImode);
510       emit_insn (gen_truncpsihi2 (result, op));
511       return result;
512     }
513   else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR)
514     {
515       /* This always works.  */
516 
517       if (CONSTANT_P (op))
518 	return gen_rtx_CONST (PSImode, op);
519 
520       result = gen_reg_rtx (PSImode);
521       emit_insn (gen_zero_extendhipsi2 (result, op));
522       return result;
523     }
524   else
525     gcc_unreachable ();
526 }
527 
528 /* Stack Layout and Calling Conventions.  */
529 
530 /* For each function, we list the gcc version and the TI version on
531    each line, where we're converting the function names.  */
532 static char const * const special_convention_function_names[] =
533 {
534   "__muldi3", "__mspabi_mpyll",
535   "__udivdi3", "__mspabi_divull",
536   "__umoddi3", "__mspabi_remull",
537   "__divdi3", "__mspabi_divlli",
538   "__moddi3", "__mspabi_remlli",
539   "__mspabi_srall",
540   "__mspabi_srlll",
541   "__mspabi_sllll",
542   "__adddf3", "__mspabi_addd",
543   "__subdf3", "__mspabi_subd",
544   "__muldf3", "__mspabi_mpyd",
545   "__divdf3", "__mspabi_divd",
546   "__mspabi_cmpd",
547   NULL
548 };
549 
550 /* TRUE if the function passed is a "speical" function.  Special
551    functions pass two DImode parameters in registers.  */
552 static bool
msp430_special_register_convention_p(const char * name)553 msp430_special_register_convention_p (const char *name)
554 {
555   int i;
556 
557   for (i = 0; special_convention_function_names[i]; i++)
558     if (!strcmp (name, special_convention_function_names[i]))
559       return true;
560 
561   return false;
562 }
563 
564 #undef  TARGET_FUNCTION_VALUE_REGNO_P
565 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p
566 
567 bool
msp430_function_value_regno_p(unsigned int regno)568 msp430_function_value_regno_p (unsigned int regno)
569 {
570   return regno == 12;
571 }
572 
573 
574 #undef  TARGET_FUNCTION_VALUE
575 #define TARGET_FUNCTION_VALUE msp430_function_value
576 
577 rtx
msp430_function_value(const_tree ret_type,const_tree fn_decl_or_type ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)578 msp430_function_value (const_tree ret_type,
579 		       const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
580 		       bool outgoing ATTRIBUTE_UNUSED)
581 {
582   return gen_rtx_REG (TYPE_MODE (ret_type), 12);
583 }
584 
585 #undef  TARGET_LIBCALL_VALUE
586 #define TARGET_LIBCALL_VALUE msp430_libcall_value
587 
588 rtx
msp430_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)589 msp430_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
590 {
591   return gen_rtx_REG (mode, 12);
592 }
593 
594 /* Implements INIT_CUMULATIVE_ARGS.  */
595 void
msp430_init_cumulative_args(CUMULATIVE_ARGS * ca,tree fntype ATTRIBUTE_UNUSED,rtx libname ATTRIBUTE_UNUSED,tree fndecl ATTRIBUTE_UNUSED,int n_named_args ATTRIBUTE_UNUSED)596 msp430_init_cumulative_args (CUMULATIVE_ARGS *ca,
597 			     tree fntype ATTRIBUTE_UNUSED,
598 			     rtx libname ATTRIBUTE_UNUSED,
599 			     tree fndecl ATTRIBUTE_UNUSED,
600 			     int n_named_args ATTRIBUTE_UNUSED)
601 {
602   const char *fname;
603   memset (ca, 0, sizeof(*ca));
604 
605   ca->can_split = 1;
606 
607   if (fndecl)
608     fname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
609   else if (libname)
610     fname = XSTR (libname, 0);
611   else
612     fname = NULL;
613 
614   if (fname && msp430_special_register_convention_p (fname))
615     ca->special_p = 1;
616 }
617 
618 /* Helper function for argument passing; this function is the common
619    code that determines where an argument will be passed.  */
620 static void
msp430_evaluate_arg(cumulative_args_t cap,machine_mode mode,const_tree type ATTRIBUTE_UNUSED,bool named)621 msp430_evaluate_arg (cumulative_args_t cap,
622 		     machine_mode mode,
623 		     const_tree type ATTRIBUTE_UNUSED,
624 		     bool named)
625 {
626   CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
627   int nregs = GET_MODE_SIZE (mode);
628   int i;
629 
630   ca->reg_count = 0;
631   ca->mem_count = 0;
632 
633   if (!named)
634     return;
635 
636   if (mode == PSImode)
637     nregs = 1;
638   else
639     nregs = (nregs + 1) / 2;
640 
641   if (ca->special_p)
642     {
643       /* Function is passed two DImode operands, in R8:R11 and
644 	 R12:15.  */
645       ca->start_reg = 8;
646       ca->reg_count = 4;
647       return;
648     }
649 
650   switch (nregs)
651     {
652     case 1:
653       for (i = 0; i < 4; i++)
654 	if (!ca->reg_used[i])
655 	  {
656 	    ca->reg_count = 1;
657 	    ca->start_reg = CA_FIRST_REG + i;
658 	    return;
659 	  }
660       break;
661     case 2:
662       for (i = 0; i < 3; i++)
663 	if (!ca->reg_used[i] && !ca->reg_used[i + 1])
664 	  {
665 	    ca->reg_count = 2;
666 	    ca->start_reg = CA_FIRST_REG + i;
667 	    return;
668 	  }
669       if (!ca->reg_used[3] && ca->can_split)
670 	{
671 	  ca->reg_count = 1;
672 	  ca->mem_count = 2;
673 	  ca->start_reg = CA_FIRST_REG + 3;
674 	  return;
675 	}
676       break;
677     case 3:
678     case 4:
679       ca->can_split = 0;
680       if (!ca->reg_used[0]
681 	  && !ca->reg_used[1]
682 	  && !ca->reg_used[2]
683 	  && !ca->reg_used[3])
684 	{
685 	  ca->reg_count = 4;
686 	  ca->start_reg = CA_FIRST_REG;
687 	  return;
688 	}
689       break;
690     }
691 }
692 
693 #undef  TARGET_PROMOTE_PROTOTYPES
694 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes
695 
696 bool
msp430_promote_prototypes(const_tree fntype ATTRIBUTE_UNUSED)697 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED)
698 {
699   return false;
700 }
701 
702 #undef  TARGET_FUNCTION_ARG
703 #define TARGET_FUNCTION_ARG msp430_function_arg
704 
705 rtx
msp430_function_arg(cumulative_args_t cap,const function_arg_info & arg)706 msp430_function_arg (cumulative_args_t cap,
707 		     const function_arg_info &arg)
708 {
709   CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
710 
711   msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
712 
713   if (ca->reg_count)
714     return gen_rtx_REG (arg.mode, ca->start_reg);
715 
716   return 0;
717 }
718 
719 #undef  TARGET_ARG_PARTIAL_BYTES
720 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes
721 
722 int
msp430_arg_partial_bytes(cumulative_args_t cap,const function_arg_info & arg)723 msp430_arg_partial_bytes (cumulative_args_t cap, const function_arg_info &arg)
724 {
725   CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
726 
727   msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
728 
729   if (ca->reg_count && ca->mem_count)
730     return ca->reg_count * UNITS_PER_WORD;
731 
732   return 0;
733 }
734 
735 #undef  TARGET_PASS_BY_REFERENCE
736 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference
737 
738 static bool
msp430_pass_by_reference(cumulative_args_t,const function_arg_info & arg)739 msp430_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
740 {
741   return (arg.mode == BLKmode
742 	  || (arg.type && TREE_CODE (arg.type) == RECORD_TYPE)
743 	  || (arg.type && TREE_CODE (arg.type) == UNION_TYPE));
744 }
745 
746 #undef  TARGET_CALLEE_COPIES
747 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_arg_info_true
748 
749 #undef  TARGET_FUNCTION_ARG_ADVANCE
750 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance
751 
752 void
msp430_function_arg_advance(cumulative_args_t cap,const function_arg_info & arg)753 msp430_function_arg_advance (cumulative_args_t cap,
754 			     const function_arg_info &arg)
755 {
756   CUMULATIVE_ARGS *ca = get_cumulative_args (cap);
757   int i;
758 
759   msp430_evaluate_arg (cap, arg.mode, arg.type, arg.named);
760 
761   if (ca->start_reg >= CA_FIRST_REG)
762     for (i = 0; i < ca->reg_count; i ++)
763       ca->reg_used[i + ca->start_reg - CA_FIRST_REG] = 1;
764 
765   ca->special_p = 0;
766 }
767 
768 #undef  TARGET_FUNCTION_ARG_BOUNDARY
769 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary
770 
771 static unsigned int
msp430_function_arg_boundary(machine_mode mode,const_tree type)772 msp430_function_arg_boundary (machine_mode mode, const_tree type)
773 {
774   if (mode == BLKmode
775       && int_size_in_bytes (type) > 1)
776     return 16;
777   if (GET_MODE_BITSIZE (mode) > 8)
778     return 16;
779   return 8;
780 }
781 
782 #undef  TARGET_RETURN_IN_MEMORY
783 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
784 
785 static bool
msp430_return_in_memory(const_tree ret_type,const_tree fntype ATTRIBUTE_UNUSED)786 msp430_return_in_memory (const_tree ret_type,
787 			 const_tree fntype ATTRIBUTE_UNUSED)
788 {
789   machine_mode mode = TYPE_MODE (ret_type);
790 
791   if (mode == BLKmode
792       || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE)
793       || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE))
794     return true;
795 
796   if (GET_MODE_SIZE (mode) > 8)
797     return true;
798 
799   return false;
800 }
801 
802 #undef  TARGET_GET_RAW_ARG_MODE
803 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode
804 
805 static fixed_size_mode
msp430_get_raw_arg_mode(int regno)806 msp430_get_raw_arg_mode (int regno)
807 {
808   return as_a <fixed_size_mode> (regno == ARG_POINTER_REGNUM
809 				 ? VOIDmode : Pmode);
810 }
811 
812 #undef  TARGET_GET_RAW_RESULT_MODE
813 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode
814 
815 static fixed_size_mode
msp430_get_raw_result_mode(int regno ATTRIBUTE_UNUSED)816 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
817 {
818   return Pmode;
819 }
820 
821 #undef  TARGET_GIMPLIFY_VA_ARG_EXPR
822 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr
823 
824 #include "gimplify.h"
825 
826 static tree
msp430_gimplify_va_arg_expr(tree valist,tree type,gimple_seq * pre_p,gimple_seq * post_p)827 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
828 			     gimple_seq *post_p)
829 {
830   tree addr, t, type_size, rounded_size, valist_tmp;
831   unsigned HOST_WIDE_INT align, boundary;
832   bool indirect;
833 
834   indirect = pass_va_arg_by_reference (type);
835   if (indirect)
836     type = build_pointer_type (type);
837 
838   align = PARM_BOUNDARY / BITS_PER_UNIT;
839   boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
840 
841   /* When we align parameter on stack for caller, if the parameter
842      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
843      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
844      here with caller.  */
845   if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
846     boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
847 
848   boundary /= BITS_PER_UNIT;
849 
850   /* Hoist the valist value into a temporary for the moment.  */
851   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
852 
853   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
854      requires greater alignment, we must perform dynamic alignment.  */
855   if (boundary > align
856       && !integer_zerop (TYPE_SIZE (type)))
857     {
858       /* FIXME: This is where this function diverts from targhooks.c:
859 	 std_gimplify_va_arg_expr().  It works, but I do not know why...  */
860       if (! POINTER_TYPE_P (type))
861 	{
862 	  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
863 		      fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
864 	  gimplify_and_add (t, pre_p);
865 
866 	  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
867 		      fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
868 				   valist_tmp,
869 				   build_int_cst (TREE_TYPE (valist),
870 						  -boundary)));
871 	  gimplify_and_add (t, pre_p);
872 	}
873     }
874   else
875     boundary = align;
876 
877   /* If the actual alignment is less than the alignment of the type,
878      adjust the type accordingly so that we don't assume strict alignment
879      when dereferencing the pointer.  */
880   boundary *= BITS_PER_UNIT;
881   if (boundary < TYPE_ALIGN (type))
882     {
883       type = build_variant_type_copy (type);
884       SET_TYPE_ALIGN (type, boundary);
885     }
886 
887   /* Compute the rounded size of the type.  */
888   type_size = size_in_bytes (type);
889   rounded_size = round_up (type_size, align);
890 
891   /* Reduce rounded_size so it's sharable with the postqueue.  */
892   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
893 
894   /* Get AP.  */
895   addr = valist_tmp;
896 
897   /* Compute new value for AP.  */
898   t = fold_build_pointer_plus (valist_tmp, rounded_size);
899   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
900   gimplify_and_add (t, pre_p);
901 
902   addr = fold_convert (build_pointer_type (type), addr);
903 
904   if (indirect)
905     addr = build_va_arg_indirect_ref (addr);
906 
907   addr = build_va_arg_indirect_ref (addr);
908 
909   return addr;
910 }
911 
912 #undef TARGET_LRA_P
913 #define TARGET_LRA_P hook_bool_void_false
914 
915 /* Addressing Modes */
916 
917 #undef  TARGET_LEGITIMATE_ADDRESS_P
918 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p
919 
920 static bool
reg_ok_for_addr(rtx r,bool strict)921 reg_ok_for_addr (rtx r, bool strict)
922 {
923   int rn = REGNO (r);
924 
925   if (strict && rn >= FIRST_PSEUDO_REGISTER)
926     rn = reg_renumber[rn];
927   if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
928     return true;
929   if (!strict)
930     return true;
931   return false;
932 }
933 
934 bool
msp430_legitimate_address_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x ATTRIBUTE_UNUSED,bool strict ATTRIBUTE_UNUSED)935 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
936 			     rtx x ATTRIBUTE_UNUSED,
937 			     bool strict ATTRIBUTE_UNUSED)
938 {
939   switch (GET_CODE (x))
940     {
941     case MEM:
942       return false;
943 
944     case PLUS:
945     case POST_INC:
946       if (REG_P (XEXP (x, 0)))
947 	{
948 	  if (GET_MODE (x) != GET_MODE (XEXP (x, 0)))
949 	    return false;
950 	  if (!reg_ok_for_addr (XEXP (x, 0), strict))
951 	    return false;
952 	  if (GET_CODE (x) == POST_INC)
953 	    /* At this point, if the original rtx was a post_inc, we don't have
954 	       anything further to check.  */
955 	    return true;
956 	  switch (GET_CODE (XEXP (x, 1)))
957 	    {
958 	    case CONST:
959 	    case SYMBOL_REF:
960 	    case CONST_INT:
961 	      return true;
962 	    default:
963 	      return false;
964 	    }
965 	}
966       return false;
967 
968     case REG:
969       if (!reg_ok_for_addr (x, strict))
970 	return false;
971       /* FALLTHRU */
972     case CONST:
973     case SYMBOL_REF:
974     case CONST_INT:
975       return true;
976 
977     default:
978       return false;
979     }
980 }
981 
982 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
983 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
984   msp430_addr_space_legitimate_address_p
985 
986 bool
msp430_addr_space_legitimate_address_p(machine_mode mode,rtx x,bool strict,addr_space_t as ATTRIBUTE_UNUSED)987 msp430_addr_space_legitimate_address_p (machine_mode mode,
988 					rtx x,
989 					bool strict,
990 					addr_space_t as ATTRIBUTE_UNUSED)
991 {
992   return msp430_legitimate_address_p (mode, x, strict);
993 }
994 
995 #undef  TARGET_ASM_INTEGER
996 #define TARGET_ASM_INTEGER msp430_asm_integer
997 static bool
msp430_asm_integer(rtx x,unsigned int size,int aligned_p)998 msp430_asm_integer (rtx x, unsigned int size, int aligned_p)
999 {
1000   int c = GET_CODE (x);
1001 
1002   if (size == 3 && GET_MODE (x) == PSImode)
1003     size = 4;
1004 
1005   switch (size)
1006     {
1007     case 4:
1008       if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT
1009 	  || c == PLUS || c == MINUS)
1010 	{
1011 	  fprintf (asm_out_file, "\t.long\t");
1012 	  output_addr_const (asm_out_file, x);
1013 	  fputc ('\n', asm_out_file);
1014 	  return true;
1015 	}
1016       break;
1017     }
1018   return default_assemble_integer (x, size, aligned_p);
1019 }
1020 
1021 #undef  TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1022 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra
1023 static bool
msp430_asm_output_addr_const_extra(FILE * file ATTRIBUTE_UNUSED,rtx x)1024 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
1025 {
1026   debug_rtx (x);
1027   return false;
1028 }
1029 
1030 #undef  TARGET_LEGITIMATE_CONSTANT_P
1031 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant
1032 
1033 static bool
msp430_legitimate_constant(machine_mode mode,rtx x)1034 msp430_legitimate_constant (machine_mode mode, rtx x)
1035 {
1036   return ! CONST_INT_P (x)
1037     || mode != PSImode
1038     /* GCC does not know the width of the PSImode, so make
1039        sure that it does not try to use a constant value that
1040        is out of range.  */
1041     || (INTVAL (x) < (1 << 20)
1042 	&& INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20));
1043 }
1044 
1045 
1046 #undef  TARGET_RTX_COSTS
1047 #define TARGET_RTX_COSTS msp430_rtx_costs
1048 
msp430_rtx_costs(rtx x ATTRIBUTE_UNUSED,machine_mode mode,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)1049 static bool msp430_rtx_costs (rtx	   x ATTRIBUTE_UNUSED,
1050 			      machine_mode mode,
1051 			      int	   outer_code ATTRIBUTE_UNUSED,
1052 			      int	   opno ATTRIBUTE_UNUSED,
1053 			      int *	   total,
1054 			      bool	   speed ATTRIBUTE_UNUSED)
1055 {
1056   int code = GET_CODE (x);
1057 
1058   switch (code)
1059     {
1060     case SIGN_EXTEND:
1061       if (mode == SImode && outer_code == SET)
1062 	{
1063 	  *total = COSTS_N_INSNS (4);
1064 	  return true;
1065 	}
1066       break;
1067     case ASHIFT:
1068     case ASHIFTRT:
1069     case LSHIFTRT:
1070       if (!msp430x)
1071 	{
1072 	  *total = COSTS_N_INSNS (100);
1073 	  return true;
1074 	}
1075       break;
1076     }
1077   return false;
1078 }
1079 
1080 /* Function Entry and Exit */
1081 
1082 /* The MSP430 call frame looks like this:
1083 
1084    <higher addresses>
1085    +--------------------+
1086    |                    |
1087    | Stack Arguments    |
1088    |                    |
1089    +--------------------+ <-- "arg pointer"
1090    |                    |
1091    | PC from call       |  (2 bytes for 430, 4 for TARGET_LARGE)
1092    |                    |
1093    +--------------------+
1094    | SR if this func has|
1095    | been called via an |
1096    | interrupt.         |
1097    +--------------------+  <-- SP before prologue, also AP
1098    |                    |
1099    | Saved Regs         |  (2 bytes per reg for 430, 4 per for TARGET_LARGE)
1100    |                    |
1101    +--------------------+  <-- "frame pointer"
1102    |                    |
1103    | Locals             |
1104    |                    |
1105    +--------------------+
1106    |                    |
1107    | Outgoing Args      |
1108    |                    |
1109    +--------------------+  <-- SP during function
1110    <lower addresses>
1111 
1112 */
1113 
1114 /* We use this to wrap all emitted insns in the prologue, so they get
1115    the "frame-related" (/f) flag set.  */
1116 static rtx
F(rtx x)1117 F (rtx x)
1118 {
1119   RTX_FRAME_RELATED_P (x) = 1;
1120   return x;
1121 }
1122 
1123 /* This is the one spot that decides if a register is to be saved and
1124    restored in the prologue/epilogue.  */
1125 static bool
msp430_preserve_reg_p(int regno)1126 msp430_preserve_reg_p (int regno)
1127 {
1128   /* PC, SP, SR, and the constant generator.  */
1129   if (regno <= 3)
1130     return false;
1131 
1132   /* FIXME: add interrupt, EH, etc.  */
1133   if (crtl->calls_eh_return)
1134     return true;
1135 
1136   /* Shouldn't be more than the above, but just in case...  */
1137   if (fixed_regs[regno])
1138     return false;
1139 
1140   /* For interrupt functions we must save and restore the used regs that
1141      would normally be caller-saved (R11->R15).  */
1142   if (msp430_is_interrupt_func () && regno >= 11 && regno <= 15)
1143     {
1144       if (crtl->is_leaf && df_regs_ever_live_p (regno))
1145 	/* If the interrupt func is a leaf then we only need to restore the
1146 	   caller-saved regs that are used.  */
1147 	return true;
1148       else if (!crtl->is_leaf)
1149 	/* If the interrupt function is not a leaf we must save all
1150 	   caller-saved regs in case the callee modifies them.  */
1151 	return true;
1152     }
1153 
1154   if (!call_used_or_fixed_reg_p (regno)
1155       && df_regs_ever_live_p (regno))
1156     return true;
1157 
1158   return false;
1159 }
1160 
1161 /* Compute all the frame-related fields in our machine_function
1162    structure.  */
1163 static void
msp430_compute_frame_info(void)1164 msp430_compute_frame_info (void)
1165 {
1166   int i;
1167 
1168   cfun->machine->computed = 1;
1169   cfun->machine->framesize_regs = 0;
1170   cfun->machine->framesize_locals = get_frame_size ();
1171   cfun->machine->framesize_outgoing = crtl->outgoing_args_size;
1172 
1173   for (i = 0; i < ARG_POINTER_REGNUM; i ++)
1174     if (msp430_preserve_reg_p (i))
1175       {
1176 	cfun->machine->need_to_save[i] = 1;
1177 	cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
1178       }
1179     else
1180       cfun->machine->need_to_save[i] = 0;
1181 
1182   if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
1183     cfun->machine->framesize_locals ++;
1184 
1185   cfun->machine->framesize = (cfun->machine->framesize_regs
1186 			      + cfun->machine->framesize_locals
1187 			      + cfun->machine->framesize_outgoing);
1188 }
1189 
1190 /* Attribute Handling.  */
1191 
1192 const char * const  ATTR_INTR   = "interrupt";
1193 const char * const  ATTR_WAKEUP = "wakeup";
1194 const char * const  ATTR_NAKED  = "naked";
1195 const char * const  ATTR_REENT  = "reentrant";
1196 const char * const  ATTR_CRIT   = "critical";
1197 const char * const  ATTR_LOWER  = "lower";
1198 const char * const  ATTR_UPPER  = "upper";
1199 const char * const  ATTR_EITHER = "either";
1200 const char * const  ATTR_NOINIT = "noinit";
1201 const char * const  ATTR_PERSIST = "persistent";
1202 
1203 static inline bool
has_attr(const char * attr,tree decl)1204 has_attr (const char * attr, tree decl)
1205 {
1206   if (decl == NULL_TREE)
1207     return false;
1208   return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1209 }
1210 
1211 static bool
1212 is_interrupt_func (tree decl = current_function_decl)
1213 {
1214   return has_attr (ATTR_INTR, decl);
1215 }
1216 
1217 /* Returns true if the current function has the "interrupt" attribute.  */
1218 
1219 bool
msp430_is_interrupt_func(void)1220 msp430_is_interrupt_func (void)
1221 {
1222   return is_interrupt_func (current_function_decl);
1223 }
1224 
1225 static bool
1226 is_wakeup_func (tree decl = current_function_decl)
1227 {
1228   return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl);
1229 }
1230 
1231 static inline bool
1232 is_naked_func (tree decl = current_function_decl)
1233 {
1234   return has_attr (ATTR_NAKED, decl);
1235 }
1236 
1237 static inline bool
1238 is_reentrant_func (tree decl = current_function_decl)
1239 {
1240   return has_attr (ATTR_REENT, decl);
1241 }
1242 
1243 static inline bool
1244 is_critical_func (tree decl = current_function_decl)
1245 {
1246   return has_attr (ATTR_CRIT, decl);
1247 }
1248 
1249 static bool
1250 has_section_name (const char * name, tree decl = current_function_decl)
1251 {
1252   if (decl == NULL_TREE)
1253     return false;
1254   return (DECL_SECTION_NAME (decl)
1255 	  && (strcmp (name, DECL_SECTION_NAME (decl)) == 0));
1256 }
1257 
1258 #undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
1259 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
1260   msp430_allocate_stack_slots_for_args
1261 
1262 static bool
msp430_allocate_stack_slots_for_args(void)1263 msp430_allocate_stack_slots_for_args (void)
1264 {
1265   /* Naked functions should not allocate stack slots for arguments.  */
1266   return ! is_naked_func ();
1267 }
1268 
1269 #undef TARGET_WARN_FUNC_RETURN
1270 #define TARGET_WARN_FUNC_RETURN msp430_warn_func_return
1271 
1272 static bool
msp430_warn_func_return(tree decl)1273 msp430_warn_func_return (tree decl)
1274 {
1275   /* Naked functions are implemented entirely in assembly, including the
1276      return sequence, so suppress warnings about this.  */
1277   return !is_naked_func (decl);
1278 }
1279 
1280 /* Verify MSP430 specific attributes.  */
1281 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0)
1282 
1283 static tree
msp430_attr(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)1284 msp430_attr (tree * node,
1285 	     tree   name,
1286 	     tree   args,
1287 	     int    flags ATTRIBUTE_UNUSED,
1288 	     bool * no_add_attrs)
1289 {
1290   gcc_assert (DECL_P (* node));
1291 
1292   /* Only the interrupt attribute takes an argument.  */
1293   if (args != NULL)
1294     {
1295       tree value = TREE_VALUE (args);
1296 
1297       switch (TREE_CODE (value))
1298 	{
1299 	case STRING_CST:
1300 	  if (   strcmp (TREE_STRING_POINTER (value), "reset")
1301 	      && strcmp (TREE_STRING_POINTER (value), "nmi")
1302 	      && strcmp (TREE_STRING_POINTER (value), "watchdog"))
1303 	    /* Allow the attribute to be added - the linker script
1304 	       being used may still recognise this name.  */
1305 	    warning (OPT_Wattributes,
1306 		     "unrecognized interrupt vector argument of %qE attribute",
1307 		     name);
1308 	  break;
1309 
1310 	case INTEGER_CST:
1311 	  if (wi::gtu_p (wi::to_wide (value), 63))
1312 	    /* Allow the attribute to be added - the linker script
1313 	       being used may still recognise this value.  */
1314 	    warning (OPT_Wattributes,
1315 		     "numeric argument of %qE attribute must be in range 0..63",
1316 		     name);
1317 	  break;
1318 
1319 	default:
1320 	  warning (OPT_Wattributes,
1321 		   "argument of %qE attribute is not a string constant "
1322 		   "or number", name);
1323 	  *no_add_attrs = true;
1324 	  break;
1325 	}
1326     }
1327 
1328   const char * message = NULL;
1329 
1330   if (TREE_CODE (* node) != FUNCTION_DECL)
1331     {
1332       message = "%qE attribute only applies to functions";
1333     }
1334   else if (TREE_NAME_EQ (name, ATTR_INTR))
1335     {
1336       if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE
1337 	  && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node))))
1338 	message = "interrupt handlers must be void";
1339       else
1340 	{
1341 	  /* Ensure interrupt handlers never get optimised out.  */
1342 	  TREE_USED (* node) = 1;
1343 	  DECL_PRESERVE_P (* node) = 1;
1344 	}
1345       if (is_critical_func (* node))
1346 	{
1347 	  /* We always ignore the critical attribute when interrupt and
1348 	     critical are used together.  */
1349 	  warning (OPT_Wattributes,
1350 		   "critical attribute has no effect on interrupt functions");
1351 	  DECL_ATTRIBUTES (*node) = remove_attribute (ATTR_CRIT,
1352 						      DECL_ATTRIBUTES (* node));
1353 	}
1354     }
1355   else if (TREE_NAME_EQ (name, ATTR_CRIT))
1356     {
1357       if (is_interrupt_func ( *node))
1358 	message = "critical attribute has no effect on interrupt functions";
1359     }
1360 
1361   if (message)
1362     {
1363       warning (OPT_Wattributes, message, name);
1364       * no_add_attrs = true;
1365     }
1366 
1367   return NULL_TREE;
1368 }
1369 
1370 static tree
msp430_section_attr(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs ATTRIBUTE_UNUSED)1371 msp430_section_attr (tree * node,
1372 		     tree   name,
1373 		     tree   args,
1374 		     int    flags ATTRIBUTE_UNUSED,
1375 		     bool * no_add_attrs ATTRIBUTE_UNUSED)
1376 {
1377   gcc_assert (DECL_P (* node));
1378   gcc_assert (args == NULL);
1379 
1380   const char * message = NULL;
1381 
1382   /* The "noinit" and "section" attributes are handled generically, so we
1383      cannot set up additional target-specific attribute exclusions using the
1384      existing mechanism.  */
1385   if (has_attr (ATTR_NOINIT, *node))
1386     message = G_("ignoring attribute %qE because it conflicts with "
1387 		 "attribute %<noinit%>");
1388   else if (has_attr ("section", *node) && !TREE_NAME_EQ (name, "lower"))
1389     message = G_("ignoring attribute %qE because it conflicts with "
1390 		 "attribute %<section%>");
1391   /* It does not make sense to use upper/lower/either attributes without
1392      -mlarge.
1393      Without -mlarge, "lower" is the default and only region, so is redundant.
1394      Without -mlarge, "upper" will (and "either" might) place code/data in the
1395      upper region, which for data could result in relocation overflows, and for
1396      code could result in stack mismanagement and incorrect call/return
1397      instructions.  */
1398   else if (!TARGET_LARGE)
1399     message = G_("%qE attribute ignored.  Large memory model (%<-mlarge%>) "
1400 		 "is required.");
1401 
1402   if (message)
1403     {
1404       warning (OPT_Wattributes, message, name);
1405       * no_add_attrs = true;
1406     }
1407 
1408   return NULL_TREE;
1409 }
1410 
1411 static tree
msp430_persist_attr(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs ATTRIBUTE_UNUSED)1412 msp430_persist_attr (tree *node,
1413 		  tree   name,
1414 		  tree   args,
1415 		  int    flags ATTRIBUTE_UNUSED,
1416 		  bool * no_add_attrs ATTRIBUTE_UNUSED)
1417 {
1418   const char * message = NULL;
1419 
1420   gcc_assert (DECL_P (* node));
1421   gcc_assert (args == NULL);
1422   gcc_assert (TREE_NAME_EQ (name, ATTR_PERSIST));
1423 
1424   /* Check for the section attribute separately from DECL_SECTION_NAME so
1425      we can provide a clearer warning.  */
1426   if (has_attr ("section", *node))
1427     message = G_("ignoring attribute %qE because it conflicts with "
1428 		 "attribute %<section%>");
1429   /* Check that it's possible for the variable to have a section.  */
1430   else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p)
1431 	   && (DECL_SECTION_NAME (*node)))
1432     message = G_("%qE attribute cannot be applied to variables with specific "
1433 		 "sections");
1434   else if (has_attr (ATTR_NOINIT, *node))
1435     message = G_("ignoring attribute %qE because it conflicts with "
1436 		 "attribute %<noinit%>");
1437   else if (TREE_CODE (*node) != VAR_DECL)
1438     message = G_("%qE attribute only applies to variables");
1439   else if (!TREE_STATIC (*node) && !TREE_PUBLIC (*node)
1440 	   && !DECL_EXTERNAL (*node))
1441     message = G_("%qE attribute has no effect on automatic variables");
1442   else if (DECL_COMMON (*node) || DECL_INITIAL (*node) == NULL)
1443     message = G_("variables marked with %qE attribute must be initialized");
1444   else
1445     /* It's not clear if there is anything that can be set here to prevent the
1446        front end placing the variable before the back end can handle it, in a
1447        similar way to how DECL_COMMON is cleared for .noinit variables in
1448        handle_noinit_attribute (gcc/c-family/c-attribs.c).
1449        So just place the variable in the .persistent section now.  */
1450     set_decl_section_name (* node, ".persistent");
1451 
1452   if (message)
1453     {
1454       warning (OPT_Wattributes, message, name);
1455       * no_add_attrs = true;
1456     }
1457 
1458   return NULL_TREE;
1459 }
1460 
1461 /* Helper to define attribute exclusions.  */
1462 #define ATTR_EXCL(name, function, type, variable)	\
1463   { name, function, type, variable }
1464 
1465 /* "reentrant", "critical" and "naked" functions must conflict because
1466    they all modify the prologue or epilogue of functions in mutually exclusive
1467    ways.  */
1468 static const struct attribute_spec::exclusions attr_reent_exclusions[] =
1469 {
1470   ATTR_EXCL (ATTR_NAKED, true, true, true),
1471   ATTR_EXCL (ATTR_CRIT, true, true, true),
1472   ATTR_EXCL (NULL, false, false, false)
1473 };
1474 
1475 static const struct attribute_spec::exclusions attr_naked_exclusions[] =
1476 {
1477   ATTR_EXCL (ATTR_REENT, true, true, true),
1478   ATTR_EXCL (ATTR_CRIT, true, true, true),
1479   ATTR_EXCL (NULL, false, false, false)
1480 };
1481 
1482 static const struct attribute_spec::exclusions attr_crit_exclusions[] =
1483 {
1484   ATTR_EXCL (ATTR_REENT, true, true, true),
1485   ATTR_EXCL (ATTR_NAKED, true, true, true),
1486   ATTR_EXCL (NULL, false, false, false)
1487 };
1488 
1489 /* Attributes which put the given object in a specific section must conflict
1490    with one another.  */
1491 static const struct attribute_spec::exclusions attr_lower_exclusions[] =
1492 {
1493   ATTR_EXCL (ATTR_UPPER, true, true, true),
1494   ATTR_EXCL (ATTR_EITHER, true, true, true),
1495   ATTR_EXCL (ATTR_PERSIST, true, true, true),
1496   ATTR_EXCL (NULL, false, false, false)
1497 };
1498 
1499 static const struct attribute_spec::exclusions attr_upper_exclusions[] =
1500 {
1501   ATTR_EXCL (ATTR_LOWER, true, true, true),
1502   ATTR_EXCL (ATTR_EITHER, true, true, true),
1503   ATTR_EXCL (ATTR_PERSIST, true, true, true),
1504   ATTR_EXCL (NULL, false, false, false)
1505 };
1506 
1507 static const struct attribute_spec::exclusions attr_either_exclusions[] =
1508 {
1509   ATTR_EXCL (ATTR_LOWER, true, true, true),
1510   ATTR_EXCL (ATTR_UPPER, true, true, true),
1511   ATTR_EXCL (ATTR_PERSIST, true, true, true),
1512   ATTR_EXCL (NULL, false, false, false)
1513 };
1514 
1515 static const struct attribute_spec::exclusions attr_persist_exclusions[] =
1516 {
1517   ATTR_EXCL (ATTR_LOWER, true, true, true),
1518   ATTR_EXCL (ATTR_UPPER, true, true, true),
1519   ATTR_EXCL (ATTR_EITHER, true, true, true),
1520   ATTR_EXCL (NULL, false, false, false)
1521 };
1522 
1523 #undef  TARGET_ATTRIBUTE_TABLE
1524 #define TARGET_ATTRIBUTE_TABLE		msp430_attribute_table
1525 
1526 /* Table of MSP430-specific attributes.  */
1527 const struct attribute_spec msp430_attribute_table[] =
1528   {
1529     /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
1530 	 affects_type_identity, handler, exclude } */
1531     { ATTR_INTR,	0, 1, true,  false, false, false, msp430_attr, NULL },
1532     { ATTR_NAKED,       0, 0, true,  false, false, false, msp430_attr,
1533       attr_naked_exclusions },
1534     { ATTR_REENT,       0, 0, true,  false, false, false, msp430_attr,
1535       attr_reent_exclusions },
1536     { ATTR_CRIT,	0, 0, true,  false, false, false, msp430_attr,
1537       attr_crit_exclusions },
1538     { ATTR_WAKEUP,      0, 0, true,  false, false, false, msp430_attr, NULL },
1539 
1540     { ATTR_LOWER,       0, 0, true,  false, false, false, msp430_section_attr,
1541       attr_lower_exclusions },
1542     { ATTR_UPPER,       0, 0, true,  false, false, false, msp430_section_attr,
1543       attr_upper_exclusions },
1544     { ATTR_EITHER,      0, 0, true,  false, false, false, msp430_section_attr,
1545       attr_either_exclusions },
1546 
1547     { ATTR_PERSIST,     0, 0, true,  false, false, false, msp430_persist_attr,
1548       attr_persist_exclusions },
1549 
1550     { NULL,		0, 0, false, false, false, false, NULL,  NULL }
1551   };
1552 
1553 #undef TARGET_HANDLE_GENERIC_ATTRIBUTE
1554 #define TARGET_HANDLE_GENERIC_ATTRIBUTE msp430_handle_generic_attribute
1555 
1556 tree
msp430_handle_generic_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)1557 msp430_handle_generic_attribute (tree *node,
1558 				 tree   name,
1559 				 tree   args ATTRIBUTE_UNUSED,
1560 				 int    flags ATTRIBUTE_UNUSED,
1561 				 bool *no_add_attrs)
1562 
1563 {
1564   const char *message = NULL;
1565 
1566   /* The front end has set up an exclusion between the "noinit" and "section"
1567      attributes.  */
1568   if (!(TREE_NAME_EQ (name, ATTR_NOINIT) || TREE_NAME_EQ (name, "section")))
1569     return NULL_TREE;
1570 
1571   /* We allow the "lower" attribute to be used on variables with the "section"
1572      attribute.  */
1573   if (has_attr (ATTR_LOWER, *node) && !TREE_NAME_EQ (name, "section"))
1574     message = G_("ignoring attribute %qE because it conflicts with "
1575 		 "attribute %<lower%>");
1576   else if (has_attr (ATTR_UPPER, *node))
1577     message = G_("ignoring attribute %qE because it conflicts with "
1578 		 "attribute %<upper%>");
1579   else if (has_attr (ATTR_EITHER, *node))
1580     message = G_("ignoring attribute %qE because it conflicts with "
1581 		 "attribute %<either%>");
1582   else if (has_attr (ATTR_PERSIST, *node))
1583     message = G_("ignoring attribute %qE because it conflicts with "
1584 		 "attribute %<persistent%>");
1585 
1586   if (message)
1587     {
1588       warning (OPT_Wattributes, message, name);
1589       *no_add_attrs = true;
1590     }
1591 
1592   return NULL_TREE;
1593 }
1594 
1595 /* Given a non-automatic VAR_DECL which can possibly have a section, return
1596    true if the variable will definitely be placed in the lower memory
1597    region (below address 0x10000).  */
1598 static bool
msp430_var_in_low_mem(tree decl)1599 msp430_var_in_low_mem (tree decl)
1600 {
1601   gcc_assert (VAR_P (decl));
1602 
1603   /* "noinit" variables are always placed in the lower memory region.  */
1604   if (has_attr (ATTR_UPPER, decl)
1605       || has_attr (ATTR_EITHER, decl)
1606       || has_attr (ATTR_PERSIST, decl)
1607       /* Unless the variable is marked with the lower or noinit attribute, we
1608 	 cannot assume that it is in the lower region if it is marked with the
1609 	 section attribute or -mdata-region={upper,either,none} have been
1610 	 passed.
1611 	 The noinit and section attributes conflict.  */
1612       || (!has_attr (ATTR_LOWER, decl) && !has_attr (ATTR_NOINIT, decl)
1613 	  && (has_attr ("section", decl)
1614 	      || msp430_data_region == MSP430_REGION_UPPER
1615 	      || msp430_data_region == MSP430_REGION_EITHER
1616 	      || msp430_data_region == MSP430_REGION_ANY)))
1617     return false;
1618   return true;
1619 }
1620 
1621 #undef TARGET_ENCODE_SECTION_INFO
1622 #define TARGET_ENCODE_SECTION_INFO msp430_encode_section_info
1623 
1624 /* Encode whether a SYMBOL_REF is definitely in the lower memory region.  */
1625 static void
msp430_encode_section_info(tree decl,rtx rtl,int first)1626 msp430_encode_section_info (tree decl, rtx rtl, int first)
1627 {
1628   rtx symbol;
1629   default_encode_section_info (decl, rtl, first);
1630 
1631   /* Careful not to prod global register variables.  */
1632   if (!MEM_P (rtl))
1633     return;
1634   symbol = XEXP (rtl, 0);
1635   if (GET_CODE (symbol) != SYMBOL_REF)
1636     return;
1637 
1638   if (VAR_P (decl)
1639       && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1640       && msp430_var_in_low_mem (decl))
1641     SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOW_MEM;
1642 }
1643 
1644 #undef  TARGET_ASM_FUNCTION_PROLOGUE
1645 #define TARGET_ASM_FUNCTION_PROLOGUE	msp430_start_function
1646 
1647 static void
msp430_start_function(FILE * outfile)1648 msp430_start_function (FILE *outfile)
1649 {
1650   int r, n;
1651 
1652   fprintf (outfile, "; start of function\n");
1653 
1654   if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE)
1655     {
1656       fprintf (outfile, "; attributes: ");
1657       if (is_naked_func ())
1658 	fprintf (outfile, "naked ");
1659       if (msp430_is_interrupt_func ())
1660 	fprintf (outfile, "interrupt ");
1661       if (is_reentrant_func ())
1662 	fprintf (outfile, "reentrant ");
1663       if (is_critical_func ())
1664 	fprintf (outfile, "critical ");
1665       if (is_wakeup_func ())
1666 	fprintf (outfile, "wakeup ");
1667       fprintf (outfile, "\n");
1668     }
1669 
1670   fprintf (outfile, "; framesize_regs:     %d\n",
1671 	   cfun->machine->framesize_regs);
1672   fprintf (outfile, "; framesize_locals:   %d\n",
1673 	   cfun->machine->framesize_locals);
1674   fprintf (outfile, "; framesize_outgoing: %d\n",
1675 	   cfun->machine->framesize_outgoing);
1676   fprintf (outfile, "; framesize:          %d\n", cfun->machine->framesize);
1677   fprintf (outfile, "; elim ap -> fp       %d\n",
1678 	   msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
1679 					      FRAME_POINTER_REGNUM));
1680   fprintf (outfile, "; elim fp -> sp       %d\n",
1681 	   msp430_initial_elimination_offset (FRAME_POINTER_REGNUM,
1682 					      STACK_POINTER_REGNUM));
1683 
1684   n = 0;
1685   fprintf (outfile, "; saved regs:");
1686   for (r = 0; r < ARG_POINTER_REGNUM; r++)
1687     if (cfun->machine->need_to_save[r])
1688       {
1689 	fprintf (outfile, " %s", reg_names[r]);
1690 	n = 1;
1691       }
1692   if (n == 0)
1693     fprintf (outfile, "(none)");
1694   fprintf (outfile, "\n");
1695 }
1696 
1697 /* Common code to change the stack pointer.  */
1698 static void
increment_stack(HOST_WIDE_INT amount)1699 increment_stack (HOST_WIDE_INT amount)
1700 {
1701   rtx inc;
1702   rtx sp =  stack_pointer_rtx;
1703 
1704   if (amount == 0)
1705     return;
1706 
1707   if (amount < 0)
1708     {
1709       inc = GEN_INT (- amount);
1710       if (TARGET_LARGE)
1711 	F (emit_insn (gen_subpsi3 (sp, sp, inc)));
1712       else
1713 	F (emit_insn (gen_subhi3 (sp, sp, inc)));
1714     }
1715   else
1716     {
1717       inc = GEN_INT (amount);
1718       if (TARGET_LARGE)
1719 	emit_insn (gen_addpsi3 (sp, sp, inc));
1720       else
1721 	emit_insn (gen_addhi3 (sp, sp, inc));
1722     }
1723 }
1724 
1725 void
msp430_start_function(FILE * file,const char * name,tree decl)1726 msp430_start_function (FILE *file, const char *name, tree decl)
1727 {
1728   tree int_attr;
1729 
1730   int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
1731   if (int_attr != NULL_TREE)
1732     {
1733       tree intr_vector = TREE_VALUE (int_attr);
1734 
1735       if (intr_vector != NULL_TREE)
1736 	{
1737 	  char buf[101];
1738 
1739 	  /* Interrupt vector sections should be unique, but use of weak
1740 	     functions implies multiple definitions.  */
1741 	  if (DECL_WEAK (decl))
1742 	    {
1743 	      error ("argument to interrupt attribute is unsupported for weak "
1744 		     "functions");
1745 	    }
1746 
1747 	  intr_vector = TREE_VALUE (intr_vector);
1748 
1749 	  /* The interrupt attribute has a vector value.  Turn this into a
1750 	     section name, switch to that section and put the address of
1751 	     the current function into that vector slot.  Note msp430_attr()
1752 	     has already verified the vector name for us.  */
1753 	  if (TREE_CODE (intr_vector) == STRING_CST)
1754 	    sprintf (buf, "__interrupt_vector_%.80s",
1755 		     TREE_STRING_POINTER (intr_vector));
1756 	  else /* TREE_CODE (intr_vector) == INTEGER_CST */
1757 	    sprintf (buf, "__interrupt_vector_%u",
1758 		     (unsigned int) TREE_INT_CST_LOW (intr_vector));
1759 
1760 	  switch_to_section (get_section (buf, SECTION_CODE, decl));
1761 	  fputs ("\t.word\t", file);
1762 	  assemble_name (file, name);
1763 	  fputc ('\n', file);
1764 	  fputc ('\t', file);
1765 	}
1766     }
1767 
1768   switch_to_section (function_section (decl));
1769   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
1770   ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
1771 }
1772 
1773 static const char * const lower_prefix = ".lower";
1774 static const char * const upper_prefix = ".upper";
1775 static const char * const either_prefix = ".either";
1776 
1777 /* Generate a prefix for a section name, based upon
1778    the region into which the object should be placed.  */
1779 
1780 static const char *
gen_prefix(tree decl)1781 gen_prefix (tree decl)
1782 {
1783   if (DECL_ONE_ONLY (decl))
1784     return NULL;
1785 
1786   /* If the user has specified a particular section then do not use any
1787      prefix.  */
1788   if (has_attr ("section", decl))
1789     return NULL;
1790 
1791   /* If the function has been put in the .lowtext section (because it is an
1792      interrupt handler, and the large memory model is used), then do not add
1793      any prefixes.  */
1794   if (has_section_name (".lowtext", decl))
1795     return NULL;
1796 
1797   /* Memory regions require the large memory model.  */
1798   if (!TARGET_LARGE)
1799     return NULL;
1800 
1801   /* Note that we always apply the lower prefix when the attribute has been
1802      used.  But we only apply the lower prefix when the lower region has been
1803      specified by a command line option if -muse-lower-region-prefix has also
1804      been passed.  */
1805   if (has_attr (ATTR_LOWER, decl))
1806     return lower_prefix;
1807 
1808   if (has_attr (ATTR_UPPER, decl))
1809     return upper_prefix;
1810 
1811   if (has_attr (ATTR_EITHER, decl))
1812     return either_prefix;
1813 
1814   if (TREE_CODE (decl) == FUNCTION_DECL)
1815     {
1816       if ((msp430_code_region == MSP430_REGION_LOWER)
1817 	  && TARGET_USE_LOWER_REGION_PREFIX)
1818 	return lower_prefix;
1819 
1820       if (msp430_code_region == MSP430_REGION_UPPER)
1821 	return upper_prefix;
1822 
1823       if (msp430_code_region == MSP430_REGION_EITHER)
1824 	return either_prefix;
1825     }
1826   else
1827     {
1828       if ((msp430_data_region == MSP430_REGION_LOWER)
1829 	  && TARGET_USE_LOWER_REGION_PREFIX)
1830 	return lower_prefix;
1831 
1832       if (msp430_data_region == MSP430_REGION_UPPER)
1833 	return upper_prefix;
1834 
1835       if (msp430_data_region == MSP430_REGION_EITHER)
1836 	return either_prefix;
1837     }
1838 
1839   return NULL;
1840 }
1841 
1842 static section * persist_section;
1843 
1844 #undef  TARGET_ASM_INIT_SECTIONS
1845 #define TARGET_ASM_INIT_SECTIONS msp430_init_sections
1846 
1847 static void
msp430_init_sections(void)1848 msp430_init_sections (void)
1849 {
1850   persist_section = get_unnamed_section (0, output_section_asm_op,
1851 					 ".section .persistent,\"aw\"");
1852 }
1853 
1854 #undef  TARGET_ASM_SELECT_SECTION
1855 #define TARGET_ASM_SELECT_SECTION msp430_select_section
1856 
1857 static section *
msp430_select_section(tree decl,int reloc,unsigned HOST_WIDE_INT align)1858 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
1859 {
1860   const char *prefix;
1861   const char *sec_name;
1862   const char *base_sec_name;
1863 
1864   gcc_assert (decl != NULL_TREE);
1865 
1866   if (TREE_CODE (decl) == STRING_CST
1867       || TREE_CODE (decl) == CONSTRUCTOR
1868       || TREE_CODE (decl) == INTEGER_CST
1869       || TREE_CODE (decl) == VECTOR_CST
1870       || TREE_CODE (decl) == COMPLEX_CST)
1871     return default_select_section (decl, reloc, align);
1872 
1873   /* In large mode we must make sure that interrupt handlers are put into
1874      low memory as the vector table only accepts 16-bit addresses.  */
1875   if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
1876       && is_interrupt_func (decl))
1877     return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
1878 
1879   if (has_attr (ATTR_PERSIST, decl))
1880     return persist_section;
1881 
1882   /* ATTR_NOINIT is handled generically.  */
1883   if (has_attr (ATTR_NOINIT, decl))
1884     return default_elf_select_section (decl, reloc, align);
1885 
1886   prefix = gen_prefix (decl);
1887 
1888   switch (categorize_decl_for_section (decl, reloc))
1889     {
1890     case SECCAT_TEXT:
1891       if (!prefix)
1892 	return text_section;
1893       base_sec_name = ".text";
1894       break;
1895     case SECCAT_DATA:
1896       if (!prefix)
1897 	return data_section;
1898       base_sec_name = ".data";
1899       break;
1900     case SECCAT_BSS:
1901       if (!prefix)
1902 	return bss_section;
1903       base_sec_name = ".bss";
1904       break;
1905     case SECCAT_RODATA:
1906       if (!prefix)
1907 	return readonly_data_section;
1908       base_sec_name = ".rodata";
1909       break;
1910 
1911     /* Enable merging of constant data by the GNU linker using
1912        default_elf_select_section and therefore enabling creation of
1913        sections with the SHF_MERGE flag.  */
1914     case SECCAT_RODATA_MERGE_STR:
1915     case SECCAT_RODATA_MERGE_STR_INIT:
1916     case SECCAT_RODATA_MERGE_CONST:
1917       return default_elf_select_section (decl, reloc, align);
1918 
1919     /* The sections listed below are not supported for MSP430.
1920        They should not be generated, but in case they are, we use
1921        default_select_section so they get placed in sections
1922        the msp430 assembler and linker understand.  */
1923     /* "small data" sections are not supported.  */
1924     case SECCAT_SRODATA:
1925     case SECCAT_SDATA:
1926     case SECCAT_SBSS:
1927     /* Thread-local storage (TLS) is not supported.  */
1928     case SECCAT_TDATA:
1929     case SECCAT_TBSS:
1930     /* Sections used by a dynamic linker are not supported.  */
1931     case SECCAT_DATA_REL:
1932     case SECCAT_DATA_REL_LOCAL:
1933     case SECCAT_DATA_REL_RO:
1934     case SECCAT_DATA_REL_RO_LOCAL:
1935       return default_select_section (decl, reloc, align);
1936 
1937     default:
1938       gcc_unreachable ();
1939     }
1940 
1941   sec_name = ACONCAT ((prefix, base_sec_name, DECL_SECTION_NAME (decl), NULL));
1942 
1943   return get_named_section (decl, sec_name, 0);
1944 }
1945 
1946 #undef  TARGET_ASM_FUNCTION_SECTION
1947 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section
1948 
1949 static section *
msp430_function_section(tree decl,enum node_frequency freq,bool startup,bool exit)1950 msp430_function_section (tree decl, enum node_frequency freq, bool startup,
1951 			 bool exit)
1952 {
1953   const char * name;
1954 
1955   gcc_assert (DECL_SECTION_NAME (decl) != NULL);
1956   name = DECL_SECTION_NAME (decl);
1957 
1958   const char * prefix = gen_prefix (decl);
1959   if (prefix == NULL
1960       || strncmp (name, prefix, strlen (prefix)) == 0)
1961     return default_function_section (decl, freq, startup, exit);
1962 
1963   name = ACONCAT ((prefix, name, NULL));
1964   return get_named_section (decl, name, 0);
1965 }
1966 
1967 #undef  TARGET_SECTION_TYPE_FLAGS
1968 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags
1969 
1970 unsigned int
msp430_section_type_flags(tree decl,const char * name,int reloc)1971 msp430_section_type_flags (tree decl, const char * name, int reloc)
1972 {
1973   if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0)
1974     name += strlen (lower_prefix);
1975   else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0)
1976     name += strlen (upper_prefix);
1977   else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
1978     name += strlen (either_prefix);
1979   else if (strcmp (name, ".persistent") == 0)
1980     return SECTION_WRITE | SECTION_NOTYPE;
1981 
1982   return default_section_type_flags (decl, name, reloc);
1983 }
1984 
1985 #undef  TARGET_ASM_UNIQUE_SECTION
1986 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section
1987 
1988 static void
msp430_unique_section(tree decl,int reloc)1989 msp430_unique_section (tree decl, int reloc)
1990 {
1991   gcc_assert (decl != NULL_TREE);
1992 
1993   /* In large mode we must make sure that interrupt handlers are put into
1994      low memory as the vector table only accepts 16-bit addresses.  */
1995   if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
1996       && is_interrupt_func (decl))
1997     {
1998       set_decl_section_name (decl, ".lowtext");
1999       return;
2000     }
2001 
2002   default_unique_section (decl, reloc);
2003 
2004   const char * prefix;
2005 
2006   if (   TREE_CODE (decl) == STRING_CST
2007       || TREE_CODE (decl) == CONSTRUCTOR
2008       || TREE_CODE (decl) == INTEGER_CST
2009       || TREE_CODE (decl) == VECTOR_CST
2010       || TREE_CODE (decl) == COMPLEX_CST
2011       || (prefix = gen_prefix (decl)) == NULL)
2012     return;
2013 
2014   const char * dec_name = DECL_SECTION_NAME (decl);
2015   char * name = ACONCAT ((prefix, dec_name, NULL));
2016 
2017   set_decl_section_name (decl, name);
2018 }
2019 
2020 /* Emit a declaration of a common symbol.
2021    If a data region is in use then put the symbol into the
2022    equivalent .bss section instead.  */
2023 void
msp430_output_aligned_decl_common(FILE * stream,const tree decl,const char * name,unsigned HOST_WIDE_INT size,unsigned int align)2024 msp430_output_aligned_decl_common (FILE *		  stream,
2025 				   const tree		  decl,
2026 				   const char *		  name,
2027 				   unsigned HOST_WIDE_INT size,
2028 				   unsigned int		  align)
2029 {
2030   /* Only emit a common symbol if the variable does not have a specific section
2031      assigned.  */
2032   if ((msp430_data_region == MSP430_REGION_ANY
2033        || ((msp430_data_region == MSP430_REGION_LOWER)
2034 	   && !TARGET_USE_LOWER_REGION_PREFIX))
2035       && !(decl != NULL_TREE && DECL_SECTION_NAME (decl))
2036       && !has_attr (ATTR_EITHER, decl)
2037       && !has_attr (ATTR_LOWER, decl)
2038       && !has_attr (ATTR_UPPER, decl)
2039       && !has_attr (ATTR_PERSIST, decl)
2040       && !has_attr (ATTR_NOINIT, decl))
2041     {
2042       fprintf (stream, COMMON_ASM_OP);
2043       assemble_name (stream, name);
2044       fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n",
2045 	       size, align / BITS_PER_UNIT);
2046     }
2047   else
2048     {
2049       section * sec;
2050 
2051       if (decl)
2052 	sec = msp430_select_section (decl, 0, align);
2053       else
2054 	switch (msp430_data_region)
2055 	  {
2056 	  case MSP430_REGION_UPPER:
2057 	    sec = get_named_section (NULL, ".upper.bss", 0);
2058 	    break;
2059 	  case MSP430_REGION_LOWER:
2060 	    sec = get_named_section (NULL, ".lower.bss", 0);
2061 	    break;
2062 	  case MSP430_REGION_EITHER:
2063 	    sec = get_named_section (NULL, ".either.bss", 0);
2064 	    break;
2065 	  default:
2066 	    gcc_unreachable ();
2067 	  }
2068       gcc_assert (sec != NULL);
2069 
2070       switch_to_section (sec);
2071       ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT));
2072       targetm.asm_out.globalize_label (stream, name);
2073       ASM_WEAKEN_LABEL (stream, name);
2074       ASM_OUTPUT_LABEL (stream, name);
2075       ASM_OUTPUT_SKIP (stream, size ? size : 1);
2076     }
2077 }
2078 
2079 #undef TARGET_ASM_FILE_END
2080 #define TARGET_ASM_FILE_END msp430_file_end
2081 
2082 /* Emit MSPABI and GNU object attributes.
2083    Tags and values for MSPABI attributes are:
2084    OFBA_MSPABI_Tag_ISA		4
2085      MSP430	1
2086      MSP430X	2
2087    OFBA_MSPABI_Tag_Code_Model	6
2088      Small 	1
2089      Large	2
2090    OFBA_MSPABI_Tag_Data_Model	8
2091      Small 	1
2092      Large	2
2093      Restricted	3 (Unused by GNU)
2094    OFBA_MSPABI_Tag_enum_size	10 (Unused by GNU)
2095    Note that Code_Model and Data_Model are always equal for GNU.
2096    We define a new .gnu_attribute to keep track of the data region used.
2097    Tag_GNU_MSP430_Data_Region	4
2098      LOWER	1
2099      ANY	2
2100    See binutils-gdb/include/elf/msp430.h for the full details.  */
2101 static void
msp430_file_end(void)2102 msp430_file_end (void)
2103 {
2104 #ifdef HAVE_AS_GNU_ATTRIBUTE
2105   /* Enum for tag names.  */
2106   enum
2107     {
2108       OFBA_MSPABI_Tag_ISA = 4,
2109       OFBA_MSPABI_Tag_Code_Model = 6,
2110       OFBA_MSPABI_Tag_Data_Model = 8,
2111       Tag_GNU_MSP430_Data_Region = 4
2112     };
2113   /* Enum for tag values.  */
2114   enum
2115     {
2116       OFBA_MSPABI_Val_ISA_MSP430 = 1,
2117       OFBA_MSPABI_Val_ISA_MSP430X = 2,
2118       OFBA_MSPABI_Val_Model_Small = 1,
2119       OFBA_MSPABI_Val_Model_Large = 2,
2120       Tag_GNU_MSP430_Data_Region_Lower = 1,
2121       Tag_GNU_MSP430_Data_Region_Any = 2
2122     };
2123   /* .mspabi_attribute is a GNU assembler directive only.  The assembler will
2124      construct a .MSP430.attributes section based on the options it is invoked
2125      with.  The values it reads from these directives are used for validating
2126      those options.  */
2127   const char *msp430_attr = ".mspabi_attribute";
2128   const char *gnu_attr = ".gnu_attribute";
2129 
2130   /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_ISA.  */
2131   fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr, OFBA_MSPABI_Tag_ISA,
2132 	   msp430x ? OFBA_MSPABI_Val_ISA_MSP430X : OFBA_MSPABI_Val_ISA_MSP430);
2133   /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Code_Model.  */
2134   fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2135 	   OFBA_MSPABI_Tag_Code_Model,
2136 	   TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2137 	   : OFBA_MSPABI_Val_Model_Small);
2138   /* Emit .mspabi_attribute directive for OFBA_MSPABI_Tag_Data_Model.  */
2139   fprintf (asm_out_file, "\t%s %d, %d\n", msp430_attr,
2140 	   OFBA_MSPABI_Tag_Data_Model,
2141 	   TARGET_LARGE ? OFBA_MSPABI_Val_Model_Large
2142 	   : OFBA_MSPABI_Val_Model_Small);
2143 #ifdef HAVE_AS_MSPABI_ATTRIBUTE
2144   /* Emit .gnu_attribute directive for Tag_GNU_MSP430_Data_Region.  */
2145   fprintf (asm_out_file, "\t%s %d, %d\n", gnu_attr, Tag_GNU_MSP430_Data_Region,
2146 	   msp430_data_region == MSP430_REGION_LOWER
2147 	   ? Tag_GNU_MSP430_Data_Region_Lower
2148 	   : Tag_GNU_MSP430_Data_Region_Any);
2149 #endif
2150 #endif
2151 }
2152 
2153 bool
msp430_do_not_relax_short_jumps(void)2154 msp430_do_not_relax_short_jumps (void)
2155 {
2156   /* When placing code into "either" low or high memory we do not want the
2157      linker to grow the size of sections, which it can do if it is encounters a
2158      branch to a label that is too far away.  So we tell the cbranch patterns to
2159      avoid using short jumps when there is a chance that the instructions will
2160      end up in a low section.  */
2161   return
2162     msp430_code_region == MSP430_REGION_EITHER
2163     || has_attr (ATTR_EITHER, current_function_decl);
2164 }
2165 
2166 enum msp430_builtin
2167 {
2168   MSP430_BUILTIN_BIC_SR,
2169   MSP430_BUILTIN_BIS_SR,
2170   MSP430_BUILTIN_DELAY_CYCLES,
2171   MSP430_BUILTIN_max
2172 };
2173 
2174 static GTY(()) tree msp430_builtins[(int) MSP430_BUILTIN_max];
2175 
2176 static void
msp430_init_builtins(void)2177 msp430_init_builtins (void)
2178 {
2179   tree void_ftype_int = build_function_type_list (void_type_node,
2180 						  integer_type_node, NULL);
2181   tree void_ftype_longlong
2182     = build_function_type_list (void_type_node, long_long_integer_type_node,
2183 				NULL);
2184 
2185   msp430_builtins[MSP430_BUILTIN_BIC_SR] =
2186     add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
2187 			  MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
2188 
2189   msp430_builtins[MSP430_BUILTIN_BIS_SR] =
2190     add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
2191 			  MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
2192 
2193   msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
2194     add_builtin_function ( "__delay_cycles", void_ftype_longlong,
2195 			  MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL,
2196 			  NULL_TREE);
2197 }
2198 
2199 static tree
msp430_builtin_decl(unsigned code,bool initialize ATTRIBUTE_UNUSED)2200 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED)
2201 {
2202   switch (code)
2203     {
2204     case MSP430_BUILTIN_BIC_SR:
2205     case MSP430_BUILTIN_BIS_SR:
2206     case MSP430_BUILTIN_DELAY_CYCLES:
2207       return msp430_builtins[code];
2208     default:
2209       return error_mark_node;
2210     }
2211 }
2212 
2213 /* These constants are really register reads, which are faster than
2214    regular constants.  */
2215 static int
cg_magic_constant(HOST_WIDE_INT c)2216 cg_magic_constant (HOST_WIDE_INT c)
2217 {
2218   switch (c)
2219     {
2220     case 0xffff:
2221     case -1:
2222     case 0:
2223     case 1:
2224     case 2:
2225     case 4:
2226     case 8:
2227       return 1;
2228     default:
2229       return 0;
2230     }
2231 }
2232 
2233 static rtx
msp430_expand_delay_cycles(rtx arg)2234 msp430_expand_delay_cycles (rtx arg)
2235 {
2236   HOST_WIDE_INT i, c, n;
2237   /* extra cycles for MSP430X instructions */
2238 #define CYCX(M,X) (msp430x ? (X) : (M))
2239 
2240   if (GET_CODE (arg) != CONST_INT)
2241     {
2242       error ("__delay_cycles() only takes constant arguments");
2243       return NULL_RTX;
2244     }
2245 
2246   c = INTVAL (arg);
2247 
2248   if (HOST_BITS_PER_WIDE_INT > 32)
2249     {
2250       if (c < 0)
2251 	{
2252 	  error ("__delay_cycles only takes non-negative cycle counts");
2253 	  return NULL_RTX;
2254 	}
2255     }
2256 
2257   emit_insn (gen_delay_cycles_start (arg));
2258 
2259   /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles.  */
2260   if (c > 3 * 0xffff + CYCX (7, 10))
2261     {
2262       n = c;
2263       /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long
2264 	 (x<=0xffff) loop.  */
2265       if (c >= 0x10000 * 7 + CYCX (14, 16))
2266 	{
2267 	  i = 0x10000;
2268 	  c -= CYCX (14, 16) + 7 * 0x10000;
2269 	  i += c / 4;
2270 	  c %= 4;
2271 	  if ((unsigned long long) i > 0xffffffffULL)
2272 	    {
2273 	      error ("__delay_cycles is limited to 32-bit loop counts");
2274 	      return NULL_RTX;
2275 	    }
2276 	}
2277       else
2278 	{
2279 	  i = (c - CYCX (14, 16)) / 7;
2280 	  c -= CYCX (14, 16) + i * 7;
2281 	}
2282 
2283       if (cg_magic_constant (i & 0xffff))
2284 	c ++;
2285       if (cg_magic_constant ((i >> 16) & 0xffff))
2286 	c ++;
2287 
2288       if (msp430x)
2289 	emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c)));
2290       else
2291 	emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
2292     }
2293 
2294   /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is
2295      0x30004(7).  */
2296   if (c > 12)
2297     {
2298       n = c;
2299       i = (c - CYCX (7, 10)) / 3;
2300       c -= CYCX (7, 10) + i * 3;
2301 
2302       if (cg_magic_constant (i))
2303 	c ++;
2304 
2305       if (msp430x)
2306 	emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c)));
2307       else
2308 	emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c)));
2309     }
2310 
2311   while (c > 1)
2312     {
2313       emit_insn (gen_delay_cycles_2 ());
2314       c -= 2;
2315     }
2316 
2317   if (c)
2318     {
2319       emit_insn (gen_delay_cycles_1 ());
2320       c -= 1;
2321     }
2322 
2323   emit_insn (gen_delay_cycles_end (arg));
2324 
2325   return NULL_RTX;
2326 }
2327 
2328 static rtx
msp430_expand_builtin(tree exp,rtx target ATTRIBUTE_UNUSED,rtx subtarget ATTRIBUTE_UNUSED,machine_mode mode ATTRIBUTE_UNUSED,int ignore ATTRIBUTE_UNUSED)2329 msp430_expand_builtin (tree exp,
2330 		       rtx target ATTRIBUTE_UNUSED,
2331 		       rtx subtarget ATTRIBUTE_UNUSED,
2332 		       machine_mode mode ATTRIBUTE_UNUSED,
2333 		       int ignore ATTRIBUTE_UNUSED)
2334 {
2335   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2336   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
2337   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2338 
2339   if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
2340     return msp430_expand_delay_cycles (arg1);
2341 
2342   if (! msp430_is_interrupt_func ())
2343     {
2344       error ("MSP430 builtin functions only work inside interrupt handlers");
2345       return NULL_RTX;
2346     }
2347 
2348   if (! REG_P (arg1) && ! CONSTANT_P (arg1))
2349     arg1 = force_reg (mode, arg1);
2350 
2351   switch (fcode)
2352     {
2353     case MSP430_BUILTIN_BIC_SR:  emit_insn (gen_bic_SR (arg1)); break;
2354     case MSP430_BUILTIN_BIS_SR:  emit_insn (gen_bis_SR (arg1)); break;
2355     default:
2356       internal_error ("bad builtin code");
2357       break;
2358     }
2359   return NULL_RTX;
2360 }
2361 
2362 #undef  TARGET_INIT_BUILTINS
2363 #define TARGET_INIT_BUILTINS  msp430_init_builtins
2364 
2365 #undef  TARGET_EXPAND_BUILTIN
2366 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin
2367 
2368 #undef  TARGET_BUILTIN_DECL
2369 #define TARGET_BUILTIN_DECL   msp430_builtin_decl
2370 
2371 void
msp430_expand_prologue(void)2372 msp430_expand_prologue (void)
2373 {
2374   int i, j;
2375   int fs;
2376   /* Always use stack_pointer_rtx instead of calling
2377      rtx_gen_REG ourselves.  Code elsewhere in GCC assumes
2378      that there is a single rtx representing the stack pointer,
2379      namely stack_pointer_rtx, and uses == to recognize it.  */
2380   rtx sp = stack_pointer_rtx;
2381   rtx p;
2382 
2383   if (is_naked_func ())
2384     {
2385       /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2386 	 examines the output of the gen_prologue() function.  */
2387       emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2388       return;
2389     }
2390 
2391   emit_insn (gen_prologue_start_marker ());
2392 
2393   if (is_critical_func ())
2394     {
2395       emit_insn (gen_push_intr_state ());
2396       emit_insn (gen_disable_interrupts ());
2397     }
2398   else if (is_reentrant_func ())
2399     emit_insn (gen_disable_interrupts ());
2400 
2401   if (!cfun->machine->computed)
2402     msp430_compute_frame_info ();
2403 
2404   if (flag_stack_usage_info)
2405     current_function_static_stack_size = cfun->machine->framesize;
2406 
2407   if (crtl->args.pretend_args_size)
2408     {
2409       rtx note;
2410 
2411       gcc_assert (crtl->args.pretend_args_size == 2);
2412 
2413       p = emit_insn (gen_grow_and_swap ());
2414 
2415       /* Document the stack decrement...  */
2416       note = F (gen_rtx_SET (stack_pointer_rtx,
2417 			     gen_rtx_MINUS (Pmode,
2418 					    stack_pointer_rtx, GEN_INT (2))));
2419       add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2420 
2421       /* ...and the establishment of a new location for the return address.  */
2422       note = F (gen_rtx_SET (gen_rtx_MEM (Pmode,
2423 					  gen_rtx_PLUS (Pmode,
2424 							stack_pointer_rtx,
2425 							GEN_INT (-2))),
2426 			     pc_rtx));
2427       add_reg_note (p, REG_CFA_OFFSET, note);
2428       F (p);
2429     }
2430 
2431   for (i = 15; i >= 4; i--)
2432     if (cfun->machine->need_to_save[i])
2433       {
2434 	int seq, count;
2435 	rtx note;
2436 
2437 	for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --)
2438 	  ;
2439 	count = i - seq;
2440 
2441 	if (msp430x)
2442 	  {
2443 	    /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two
2444 	       bytes bigger.  */
2445 	    p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
2446 					 GEN_INT (count))));
2447 
2448 	    note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1));
2449 
2450 	    XVECEXP (note, 0, 0)
2451 	      = F (gen_rtx_SET (stack_pointer_rtx,
2452 				gen_rtx_PLUS (Pmode,
2453 					      stack_pointer_rtx,
2454 					      GEN_INT (count * (TARGET_LARGE
2455 								? -4 : -2)))));
2456 
2457 	    /* *sp-- = R[i-j] */
2458 	    /* sp+N	R10
2459 	       ...
2460 	       sp	R4  */
2461 	    for (j = 0; j < count; j ++)
2462 	      {
2463 		rtx addr;
2464 		int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2);
2465 
2466 		if (ofs)
2467 		  addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs));
2468 		else
2469 		  addr = stack_pointer_rtx;
2470 
2471 		XVECEXP (note, 0, j + 1) =
2472 		  F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
2473 				  gen_rtx_REG (Pmode, i - j)));
2474 	      }
2475 
2476 	    add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
2477 	    i -= count - 1;
2478 	  }
2479 	else
2480 	  F (emit_insn (gen_push (gen_rtx_REG (Pmode, i))));
2481       }
2482 
2483   if (frame_pointer_needed)
2484     F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp));
2485 
2486   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2487 
2488   increment_stack (- fs);
2489 
2490   emit_insn (gen_prologue_end_marker ());
2491 }
2492 
2493 void
msp430_expand_epilogue(int is_eh)2494 msp430_expand_epilogue (int is_eh)
2495 {
2496   int i;
2497   int fs;
2498   int helper_n = 0;
2499 
2500   if (is_naked_func ())
2501     {
2502       /* We must generate some RTX as thread_prologue_and_epilogue_insns()
2503 	 examines the output of the gen_epilogue() function.  */
2504       emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0)));
2505       return;
2506     }
2507 
2508   if (cfun->machine->need_to_save[10])
2509     {
2510       /* Check for a helper function.  */
2511       helper_n = 7; /* For when the loop below never sees a match.  */
2512       for (i = 9; i >= 4; i--)
2513 	if (!cfun->machine->need_to_save[i])
2514 	  {
2515 	    helper_n = 10 - i;
2516 	    for (; i >= 4; i--)
2517 	      if (cfun->machine->need_to_save[i])
2518 		{
2519 		  helper_n = 0;
2520 		  break;
2521 		}
2522 	    break;
2523 	  }
2524     }
2525 
2526   emit_insn (gen_epilogue_start_marker ());
2527 
2528   if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)),
2529 			    "main") == 0)
2530     emit_insn (gen_msp430_refsym_need_exit ());
2531 
2532   if (is_wakeup_func ())
2533     /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the
2534        status register current residing on the stack.  When this function
2535        executes its RETI instruction the SR will be updated with this saved
2536        value, thus ensuring that the processor is woken up from any low power
2537        state in which it may be residing.  */
2538     emit_insn (gen_bic_SR (GEN_INT (0xf0)));
2539 
2540   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
2541 
2542   increment_stack (fs);
2543 
2544   if (is_eh)
2545     {
2546       /* We need to add the right "SP" register save just after the
2547 	 regular ones, so that when we pop it off we're in the EH
2548 	 return frame, not this one.  This overwrites our own return
2549 	 address, but we're not going to be returning anyway.  */
2550       rtx r12 = gen_rtx_REG (Pmode, 12);
2551       rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3;
2552 
2553       /* R12 will hold the new SP.  */
2554       i = cfun->machine->framesize_regs;
2555       emit_move_insn (r12, stack_pointer_rtx);
2556       emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
2557       emit_insn (addPmode (r12, r12, GEN_INT (i)));
2558       emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode,
2559 							 stack_pointer_rtx,
2560 							 i)), r12);
2561     }
2562 
2563   for (i = 4; i <= 15; i++)
2564     if (cfun->machine->need_to_save[i])
2565       {
2566 	int seq, count;
2567 
2568 	for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++)
2569 	  ;
2570 	count = seq - i;
2571 
2572 	if (msp430x)
2573 	  {
2574 	    /* Note: With TARGET_LARGE we still use
2575 	       POPM as POPX.A is two bytes bigger.  */
2576 	    emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1),
2577 				 GEN_INT (count)));
2578 	    i += count - 1;
2579 	  }
2580 	else if (i == 11 - helper_n
2581 		 && ! msp430_is_interrupt_func ()
2582 		 && ! is_reentrant_func ()
2583 		 && ! is_critical_func ()
2584 		 && crtl->args.pretend_args_size == 0
2585 		 /* Calling the helper takes as many bytes as the POP;RET
2586 		    sequence.  */
2587 		 && helper_n > 1
2588 		 && !is_eh)
2589 	  {
2590 	    emit_jump_insn (gen_epilogue_helper (GEN_INT (helper_n)));
2591 	    return;
2592 	  }
2593 	else
2594 	  emit_insn (gen_pop (gen_rtx_REG (Pmode, i)));
2595       }
2596 
2597   if (is_eh)
2598     {
2599       /* Also pop SP, which puts us into the EH return frame.  Except
2600 	 that you can't "pop" sp, you have to just load it off the
2601 	 stack.  */
2602       emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode,
2603 						      stack_pointer_rtx));
2604     }
2605 
2606   if (crtl->args.pretend_args_size)
2607     emit_insn (gen_swap_and_shrink ());
2608 
2609   if (is_critical_func ())
2610     emit_insn (gen_pop_intr_state ());
2611   else if (is_reentrant_func ())
2612     emit_insn (gen_enable_interrupts ());
2613 
2614   emit_jump_insn (gen_msp430_return ());
2615 }
2616 
2617 /* Implements EH_RETURN_STACKADJ_RTX.  Saved and used later in
2618    m32c_emit_eh_epilogue.  */
2619 rtx
msp430_eh_return_stackadj_rtx(void)2620 msp430_eh_return_stackadj_rtx (void)
2621 {
2622   if (!cfun->machine->eh_stack_adjust)
2623     {
2624       rtx sa;
2625 
2626       sa = gen_rtx_REG (Pmode, 15);
2627       cfun->machine->eh_stack_adjust = sa;
2628     }
2629   return cfun->machine->eh_stack_adjust;
2630 }
2631 
2632 /* This function is called before reload, to "fix" the stack in
2633    preparation for an EH return.  */
2634 void
msp430_expand_eh_return(rtx eh_handler)2635 msp430_expand_eh_return (rtx eh_handler)
2636 {
2637   /* These are all Pmode */
2638   rtx ap, sa, ra, tmp;
2639 
2640   ap = arg_pointer_rtx;
2641   sa = msp430_eh_return_stackadj_rtx ();
2642   ra = eh_handler;
2643 
2644   tmp = ap;
2645   tmp = gen_rtx_PLUS (Pmode, ap, sa);
2646   tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2);
2647   tmp = gen_rtx_MEM (Pmode, tmp);
2648   emit_move_insn (tmp, ra);
2649 }
2650 
2651 #undef  TARGET_INIT_DWARF_REG_SIZES_EXTRA
2652 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra
2653 void
msp430_init_dwarf_reg_sizes_extra(tree address)2654 msp430_init_dwarf_reg_sizes_extra (tree address)
2655 {
2656   int i;
2657   rtx addr = expand_normal (address);
2658   rtx mem = gen_rtx_MEM (BLKmode, addr);
2659 
2660   /* This needs to match msp430_unwind_word_mode (above).  */
2661   if (!msp430x)
2662     return;
2663 
2664   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
2665     {
2666       unsigned int dnum = DWARF_FRAME_REGNUM (i);
2667       unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
2668 
2669       if (rnum < DWARF_FRAME_REGISTERS)
2670 	{
2671 	  HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode);
2672 
2673 	  emit_move_insn (adjust_address (mem, QImode, offset),
2674 			  gen_int_mode (4, QImode));
2675 	}
2676     }
2677 }
2678 
2679 /* This is a list of MD patterns that implement fixed-count shifts.  */
2680 static struct
2681 {
2682   const char *name;
2683   int count;
2684   int need_430x;
2685   rtx (*genfunc)(rtx,rtx);
2686 }
2687 const_shift_helpers[] =
2688 {
2689 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
2690 
2691   CSH ("slli", 1, 1, slli_1),
2692   CSH ("slll", 1, 1, slll_1),
2693   CSH ("slll", 2, 1, slll_2),
2694 
2695   CSH ("srai", 1, 0, srai_1),
2696   CSH ("sral", 1, 0, sral_1),
2697   CSH ("sral", 2, 0, sral_2),
2698 
2699   CSH ("srll", 1, 0, srll_1),
2700   CSH ("srll", 2, 1, srll_2x),
2701   { 0, 0, 0, 0 }
2702 #undef CSH
2703 };
2704 
2705 /* The MSP430 ABI defines a number of helper functions that should be
2706    used for, for example, 32-bit shifts.  This function is called to
2707    emit such a function, using the table above to optimize some
2708    cases.  */
2709 void
msp430_expand_helper(rtx * operands,const char * helper_name,bool const_variants)2710 msp430_expand_helper (rtx *operands, const char *helper_name,
2711 		      bool const_variants)
2712 {
2713   rtx c, fusage, fsym;
2714   char *helper_const = NULL;
2715   int arg1 = 12;
2716   int arg2 = 13;
2717   int arg1sz = 1;
2718   machine_mode arg0mode = GET_MODE (operands[0]);
2719   machine_mode arg1mode = GET_MODE (operands[1]);
2720   machine_mode arg2mode = GET_MODE (operands[2]);
2721   int have_430x = msp430x ? 1 : 0;
2722   int expand_mpy = strncmp (helper_name, "__mspabi_mpy",
2723 			    sizeof ("__mspabi_mpy") - 1) == 0;
2724   /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a
2725      hwmpy function.  */
2726   gcc_assert (!(expand_mpy && const_variants));
2727 
2728   /* Emit size-optimal insns for small shifts we can easily do inline.  */
2729   if (CONST_INT_P (operands[2]) && !expand_mpy)
2730     {
2731       int i;
2732 
2733       for (i=0; const_shift_helpers[i].name; i++)
2734 	{
2735 	  if (const_shift_helpers[i].need_430x <= have_430x
2736 	      && strcmp (helper_name, const_shift_helpers[i].name) == 0
2737 	      && INTVAL (operands[2]) == const_shift_helpers[i].count)
2738 	    {
2739 	      emit_insn (const_shift_helpers[i].genfunc (operands[0],
2740 							 operands[1]));
2741 	      return;
2742 	    }
2743 	}
2744     }
2745 
2746   if (arg1mode != VOIDmode && arg2mode != VOIDmode)
2747     /* Modes of arguments must be equal if not constants.  */
2748     gcc_assert (arg1mode == arg2mode);
2749 
2750   if (arg1mode == VOIDmode)
2751     arg1mode = arg0mode;
2752   if (arg2mode == VOIDmode)
2753     arg2mode = arg0mode;
2754 
2755   if (arg1mode == SImode)
2756     {
2757       arg2 = 14;
2758       arg1sz = 2;
2759     }
2760   else if (arg1mode == DImode)
2761     {
2762       arg1 = 8;
2763       arg1sz = 4;
2764       arg2 = 12;
2765     }
2766 
2767   /* Use the "const_variant" of a shift library function if requested.
2768      These are faster, but have larger code size.  */
2769   if (const_variants
2770       && CONST_INT_P (operands[2])
2771       && INTVAL (operands[2]) >= 1
2772       && INTVAL (operands[2]) <= 15)
2773     {
2774       /* Note that the INTVAL is limited in value and length by the conditional
2775 	 above.  */
2776       int len = strlen (helper_name) + 4;
2777       helper_const = (char *) xmalloc (len);
2778       snprintf (helper_const, len, "%s_%d", helper_name,
2779 		(int) INTVAL (operands[2]));
2780     }
2781 
2782   /* Setup the arguments to the helper function.  */
2783   emit_move_insn (gen_rtx_REG (arg1mode, arg1),
2784 		  operands[1]);
2785   if (!helper_const)
2786     emit_move_insn (gen_rtx_REG (arg2mode, arg2),
2787 		    operands[2]);
2788 
2789   if (expand_mpy)
2790     {
2791       if (msp430_use_f5_series_hwmult ())
2792 	fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2793 						     "_f5hw", NULL));
2794       else if (use_32bit_hwmult ())
2795 	{
2796 	  /* When the arguments are 16-bits, the 16-bit hardware multiplier is
2797 	     used.  */
2798 	  if (arg1mode == HImode)
2799 	    fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2800 							 "_hw", NULL));
2801 	  else
2802 	    fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2803 							 "_hw32", NULL));
2804 	}
2805       /* 16-bit hardware multiply.  */
2806       else if (msp430_has_hwmult ())
2807 	fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
2808 						     "_hw", NULL));
2809       else
2810 	fsym = gen_rtx_SYMBOL_REF (VOIDmode, helper_name);
2811     }
2812   else
2813     fsym = gen_rtx_SYMBOL_REF (VOIDmode,
2814 			       helper_const ? helper_const : helper_name);
2815 
2816   c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), fsym, GEN_INT (0));
2817 
2818   c = emit_call_insn (c);
2819   RTL_CONST_CALL_P (c) = 1;
2820 
2821   /* Add register usage information for the arguments to the call.  */
2822   fusage = NULL;
2823   use_regs (&fusage, arg1, arg1sz);
2824   if (!helper_const)
2825     {
2826       /* If we are expanding a shift, we only need to use the low register
2827 	 for the shift amount.  */
2828       if (!expand_mpy)
2829 	use_regs (&fusage, arg2, 1);
2830       else
2831 	use_regs (&fusage, arg2, arg1sz);
2832     }
2833   add_function_usage_to (c, fusage);
2834 
2835   emit_move_insn (operands[0],
2836 		  /* Return value will always start in R12.  */
2837 		  gen_rtx_REG (arg0mode, 12));
2838 }
2839 
2840 /* Called by cbranch<mode>4 to coerce operands into usable forms.  */
2841 void
msp430_fixup_compare_operands(machine_mode my_mode,rtx * operands)2842 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
2843 {
2844   /* constants we're looking for, not constants which are allowed.  */
2845   int const_op_idx = 1;
2846 
2847   if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
2848     const_op_idx = 2;
2849 
2850   if (GET_CODE (operands[const_op_idx]) != REG
2851       && GET_CODE (operands[const_op_idx]) != MEM)
2852     operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
2853 }
2854 
2855 /* Simplify_gen_subreg() doesn't handle memory references the way we
2856    need it to below, so we use this function for when we must get a
2857    valid subreg in a "natural" state.  */
2858 rtx
msp430_subreg(machine_mode mode,rtx r,machine_mode omode,int byte)2859 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
2860 {
2861   rtx rv;
2862   gcc_assert (mode == HImode);
2863 
2864   if (GET_CODE (r) == SUBREG
2865       && SUBREG_BYTE (r) == 0)
2866     {
2867       rtx ireg = SUBREG_REG (r);
2868       machine_mode imode = GET_MODE (ireg);
2869 
2870       /* special case for (HI (SI (PSI ...), 0)) */
2871       if (imode == PSImode
2872 	  && mode == HImode
2873 	  && byte == 0)
2874 	rv = gen_rtx_SUBREG (mode, ireg, byte);
2875       else
2876 	rv = simplify_gen_subreg (mode, ireg, imode, byte);
2877     }
2878   else if (GET_CODE (r) == MEM)
2879     {
2880       /* When byte == 2, we can be certain that we were already called with an
2881 	 identical rtx with byte == 0.  So we don't need to do anything to
2882 	 get a 2 byte offset of a (mem (post_inc)) rtx, since the address has
2883 	 already been offset by the post_inc itself.  */
2884       if (GET_CODE (XEXP (r, 0)) == POST_INC && byte == 2)
2885 	byte = 0;
2886       rv = adjust_address (r, mode, byte);
2887     }
2888   else if (GET_CODE (r) == SYMBOL_REF
2889 	   && (byte == 0 || byte == 2)
2890 	   && mode == HImode)
2891     {
2892       rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
2893       rv = gen_rtx_CONST (HImode, r);
2894     }
2895   else
2896     rv = simplify_gen_subreg (mode, r, omode, byte);
2897 
2898   if (!rv)
2899     gcc_unreachable ();
2900 
2901   return rv;
2902 }
2903 
2904 int
msp430_split_addsi(rtx * operands)2905 msp430_split_addsi (rtx *operands)
2906 {
2907   operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
2908   operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
2909   operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
2910   operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
2911   operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
2912   operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
2913 
2914   /* BZ 64160: Do not use this splitter when the dest partially overlaps the
2915      source.  */
2916   if (reg_overlap_mentioned_p (operands[3], operands[7])
2917       || reg_overlap_mentioned_p (operands[3], operands[8]))
2918     return 1;
2919 
2920   if (GET_CODE (operands[5]) == CONST_INT)
2921     operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
2922   /* Handle post_inc, for example:
2923      (set (reg:SI)
2924 	  (plus:SI (reg:SI)
2925 		   (mem:SI (post_inc:PSI (reg:PSI))))).  */
2926   else if (MEM_P (operands[5]) && GET_CODE (XEXP (operands[5], 0)) == POST_INC)
2927     {
2928       /* Strip out the post_inc from (mem (post_inc (reg))).  */
2929       operands[9] = XEXP (XEXP (operands[5], 0), 0);
2930       operands[9] = gen_rtx_MEM (HImode, operands[9]);
2931       /* Then zero extend as normal.  */
2932       operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[9]);
2933     }
2934   else
2935     operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
2936   return 0;
2937 }
2938 
2939 /* Called by movsi_x to generate the HImode operands.  */
2940 void
msp430_split_movsi(rtx * operands)2941 msp430_split_movsi (rtx *operands)
2942 {
2943   rtx op00, op02, op10, op12;
2944 
2945   op00 = msp430_subreg (HImode, operands[0], SImode, 0);
2946   op02 = msp430_subreg (HImode, operands[0], SImode, 2);
2947 
2948   if (GET_CODE (operands[1]) == CONST
2949       || GET_CODE (operands[1]) == SYMBOL_REF)
2950     {
2951       op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
2952 				   GEN_INT (0));
2953       op10 = gen_rtx_CONST (HImode, op10);
2954       op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
2955 				   GEN_INT (16));
2956       op12 = gen_rtx_CONST (HImode, op12);
2957     }
2958   else
2959     {
2960       op10 = msp430_subreg (HImode, operands[1], SImode, 0);
2961       op12 = msp430_subreg (HImode, operands[1], SImode, 2);
2962     }
2963 
2964   if (rtx_equal_p (operands[0], operands[1]))
2965     {
2966       operands[2] = op02;
2967       operands[4] = op12;
2968       operands[3] = op00;
2969       operands[5] = op10;
2970     }
2971   else if (rtx_equal_p (op00, op12)
2972 	   /* Catch the case where we are loading (rN, rN+1) from mem (rN).  */
2973 	   || (REG_P (op00) && reg_mentioned_p (op00, op10))
2974 	   /* Or storing (rN) into mem (rN).  */
2975 	   || (REG_P (op10) && reg_mentioned_p (op10, op00)))
2976     {
2977       operands[2] = op02;
2978       operands[4] = op12;
2979       operands[3] = op00;
2980       operands[5] = op10;
2981     }
2982   else
2983     {
2984       operands[2] = op00;
2985       operands[4] = op10;
2986       operands[3] = op02;
2987       operands[5] = op12;
2988     }
2989 }
2990 
2991 
2992 /* The MSPABI specifies the names of various helper functions, many of
2993    which are compatible with GCC's helpers.  This table maps the GCC
2994    name to the MSPABI name.  */
2995 static const struct
2996 {
2997   char const * const gcc_name;
2998   char const * const ti_name;
2999 }
3000 helper_function_name_mappings[] =
3001   {
3002     /* Floating point to/from integer conversions.  */
3003     { "__truncdfsf2", "__mspabi_cvtdf" },
3004     { "__extendsfdf2", "__mspabi_cvtfd" },
3005     { "__fixdfhi", "__mspabi_fixdi" },
3006     { "__fixdfsi", "__mspabi_fixdli" },
3007     { "__fixdfdi", "__mspabi_fixdlli" },
3008     { "__fixunsdfhi", "__mspabi_fixdu" },
3009     { "__fixunsdfsi", "__mspabi_fixdul" },
3010     { "__fixunsdfdi", "__mspabi_fixdull" },
3011     { "__fixsfhi", "__mspabi_fixfi" },
3012     { "__fixsfsi", "__mspabi_fixfli" },
3013     { "__fixsfdi", "__mspabi_fixflli" },
3014     { "__fixunsfhi", "__mspabi_fixfu" },
3015     { "__fixunsfsi", "__mspabi_fixful" },
3016     { "__fixunsfdi", "__mspabi_fixfull" },
3017     { "__floathisf", "__mspabi_fltif" },
3018     { "__floatsisf", "__mspabi_fltlif" },
3019     { "__floatdisf", "__mspabi_fltllif" },
3020     { "__floathidf", "__mspabi_fltid" },
3021     { "__floatsidf", "__mspabi_fltlid" },
3022     { "__floatdidf", "__mspabi_fltllid" },
3023     { "__floatunhisf", "__mspabi_fltuf" },
3024     { "__floatunsisf", "__mspabi_fltulf" },
3025     { "__floatundisf", "__mspabi_fltullf" },
3026     { "__floatunhidf", "__mspabi_fltud" },
3027     { "__floatunsidf", "__mspabi_fltuld" },
3028     { "__floatundidf", "__mspabi_fltulld" },
3029 
3030     /* Floating point comparisons.  */
3031     /* GCC uses individual functions for each comparison, TI uses one
3032        compare <=> function.  */
3033 
3034     /* Floating point arithmetic.  */
3035     { "__adddf3", "__mspabi_addd" },
3036     { "__addsf3", "__mspabi_addf" },
3037     { "__divdf3", "__mspabi_divd" },
3038     { "__divsf3", "__mspabi_divf" },
3039     { "__muldf3", "__mspabi_mpyd" },
3040     { "__mulsf3", "__mspabi_mpyf" },
3041     { "__subdf3", "__mspabi_subd" },
3042     { "__subsf3", "__mspabi_subf" },
3043     /* GCC does not use helper functions for negation.  */
3044 
3045     /* Integer multiply, divide, remainder.  */
3046     { "__mulhi3", "__mspabi_mpyi" },
3047     { "__mulsi3", "__mspabi_mpyl" },
3048     { "__muldi3", "__mspabi_mpyll" },
3049 #if 0
3050     /* Clarify signed vs unsigned first.  */
3051     { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
3052 					   (yet?) */
3053     { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
3054 					    (yet?) */
3055 #endif
3056 
3057     { "__divhi3", "__mspabi_divi" },
3058     { "__divsi3", "__mspabi_divli" },
3059     { "__divdi3", "__mspabi_divlli" },
3060     { "__udivhi3", "__mspabi_divu" },
3061     { "__udivsi3", "__mspabi_divul" },
3062     { "__udivdi3", "__mspabi_divull" },
3063     { "__modhi3", "__mspabi_remi" },
3064     { "__modsi3", "__mspabi_remli" },
3065     { "__moddi3", "__mspabi_remlli" },
3066     { "__umodhi3", "__mspabi_remu" },
3067     { "__umodsi3", "__mspabi_remul" },
3068     { "__umoddi3", "__mspabi_remull" },
3069 
3070     /* Bitwise operations.  */
3071     /* Rotation - no rotation support yet.  */
3072     /* Logical left shift - gcc already does these itself.  */
3073     /* Arithmetic left shift - gcc already does these itself.  */
3074     /* Arithmetic right shift - gcc already does these itself.  */
3075 
3076     { NULL, NULL }
3077   };
3078 
3079 /* Returns true if the current MCU supports an F5xxx series
3080    hardware multiper.  */
3081 
3082 bool
msp430_use_f5_series_hwmult(void)3083 msp430_use_f5_series_hwmult (void)
3084 {
3085   static const char * cached_match = NULL;
3086   static bool cached_result;
3087 
3088   if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
3089     return true;
3090 
3091   if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3092     return false;
3093 
3094   if (target_mcu == cached_match)
3095     return cached_result;
3096 
3097   cached_match = target_mcu;
3098 
3099   if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
3100     return cached_result = true;
3101   if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
3102     return cached_result = true;
3103   if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
3104     return cached_result = true;
3105 
3106   msp430_extract_mcu_data (target_mcu);
3107 
3108   if (extracted_mcu_data.name != NULL)
3109     return cached_result = extracted_mcu_data.hwmpy == 8;
3110 
3111   return cached_result = false;
3112 }
3113 
3114 /* Returns true if the current MCU has a second generation
3115    32-bit hardware multiplier.  */
3116 
3117 static bool
use_32bit_hwmult(void)3118 use_32bit_hwmult (void)
3119 {
3120   static const char * cached_match = NULL;
3121   static bool cached_result;
3122 
3123   if (msp430_hwmult_type == MSP430_HWMULT_LARGE)
3124     return true;
3125 
3126   if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3127     return false;
3128 
3129   if (target_mcu == cached_match)
3130     return cached_result;
3131 
3132   cached_match = target_mcu;
3133 
3134   msp430_extract_mcu_data (target_mcu);
3135   if (extracted_mcu_data.name != NULL)
3136     return cached_result = extracted_mcu_data.hwmpy == 4;
3137 
3138   return cached_result = false;
3139 }
3140 
3141 /* Returns true if the current MCU does not have a
3142    hardware multiplier of any kind.  */
3143 
3144 bool
msp430_has_hwmult(void)3145 msp430_has_hwmult (void)
3146 {
3147   static const char * cached_match = NULL;
3148   static bool cached_result;
3149 
3150   if (msp430_hwmult_type == MSP430_HWMULT_NONE)
3151     return false;
3152 
3153   /* TRUE for any other explicit hwmult specified.  */
3154   if (msp430_hwmult_type != MSP430_HWMULT_AUTO)
3155     return true;
3156 
3157   /* Now handle -mhwmult=auto.  */
3158   if (target_mcu == NULL)
3159     return false;
3160 
3161   if (target_mcu == cached_match)
3162     return cached_result;
3163 
3164   cached_match = target_mcu;
3165 
3166   msp430_extract_mcu_data (target_mcu);
3167   if (extracted_mcu_data.name != NULL)
3168     return cached_result = extracted_mcu_data.hwmpy != 0;
3169 
3170   /* If we do not recognise the MCU name, we assume that it does not support
3171      any kind of hardware multiply - this is the safest assumption to make.  */
3172   return cached_result = false;
3173 }
3174 
3175 /* This function does the same as the default, but it will replace GCC
3176    function names with the MSPABI-specified ones.  */
3177 
3178 void
msp430_output_labelref(FILE * file,const char * name)3179 msp430_output_labelref (FILE *file, const char *name)
3180 {
3181   int i;
3182 
3183   for (i = 0; helper_function_name_mappings[i].gcc_name; i++)
3184     if (strcmp (helper_function_name_mappings[i].gcc_name, name) == 0)
3185       {
3186 	name = helper_function_name_mappings[i].ti_name;
3187 	break;
3188       }
3189 
3190   /* If we have been given a specific MCU name then we may be
3191      able to make use of its hardware multiply capabilities.  */
3192   if (msp430_has_hwmult ())
3193     {
3194       if (strcmp ("__mspabi_mpyi", name) == 0)
3195 	{
3196 	  if (msp430_use_f5_series_hwmult ())
3197 	    name = "__mulhi2_f5";
3198 	  else
3199 	    name = "__mulhi2";
3200 	}
3201       else if (strcmp ("__mspabi_mpyl", name) == 0)
3202 	{
3203 	  if (msp430_use_f5_series_hwmult ())
3204 	    name = "__mulsi2_f5";
3205 	  else if (use_32bit_hwmult ())
3206 	    name = "__mulsi2_hw32";
3207 	  else
3208 	    name = "__mulsi2";
3209 	}
3210     }
3211 
3212   if (user_label_prefix[0] != 0)
3213     fputs (user_label_prefix, file);
3214 
3215   fputs (name, file);
3216 }
3217 
3218 /* Common code for msp430_print_operand...  */
3219 
3220 static void
msp430_print_operand_raw(FILE * file,rtx op)3221 msp430_print_operand_raw (FILE * file, rtx op)
3222 {
3223   HOST_WIDE_INT i;
3224 
3225   switch (GET_CODE (op))
3226     {
3227     case REG:
3228       fprintf (file, "%s", reg_names[REGNO (op)]);
3229       break;
3230 
3231     case CONST_INT:
3232       i = INTVAL (op);
3233       if (TARGET_ASM_HEX)
3234 	fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
3235       else
3236 	fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
3237       break;
3238 
3239     case CONST:
3240     case PLUS:
3241     case MINUS:
3242     case SYMBOL_REF:
3243     case LABEL_REF:
3244       output_addr_const (file, op);
3245       break;
3246 
3247     default:
3248       print_rtl (file, op);
3249       break;
3250     }
3251 }
3252 
3253 #undef  TARGET_ASM_ALIGNED_PSI_OP
3254 #define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
3255 #undef  TARGET_ASM_UNALIGNED_PSI_OP
3256 #define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
3257 
3258 #undef  TARGET_PRINT_OPERAND_ADDRESS
3259 #define TARGET_PRINT_OPERAND_ADDRESS	msp430_print_operand_addr
3260 
3261 /* Output to stdio stream FILE the assembler syntax for an
3262    instruction operand that is a memory reference whose address
3263    is ADDR.  */
3264 
3265 static void
msp430_print_operand_addr(FILE * file,machine_mode,rtx addr)3266 msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
3267 {
3268   switch (GET_CODE (addr))
3269     {
3270     case PLUS:
3271       msp430_print_operand_raw (file, XEXP (addr, 1));
3272       gcc_assert (REG_P (XEXP (addr, 0)));
3273       fprintf (file, "(%s)", reg_names[REGNO (XEXP (addr, 0))]);
3274       return;
3275 
3276     case REG:
3277       fprintf (file, "@");
3278       break;
3279 
3280     case POST_INC:
3281       fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
3282       return;
3283 
3284     case CONST:
3285     case CONST_INT:
3286     case SYMBOL_REF:
3287     case LABEL_REF:
3288       fprintf (file, "&");
3289       break;
3290 
3291     default:
3292       break;
3293     }
3294 
3295   msp430_print_operand_raw (file, addr);
3296 }
3297 
3298 /* We can only allow signed 15-bit indexes i.e. +/-32K.  */
3299 static bool
msp430_check_index_not_high_mem(rtx op)3300 msp430_check_index_not_high_mem (rtx op)
3301 {
3302   if (CONST_INT_P (op)
3303       && IN_RANGE (INTVAL (op), HOST_WIDE_INT_M1U << 15, (1 << 15) - 1))
3304     return true;
3305   return false;
3306 }
3307 
3308 /* If this returns true, we don't need a 430X insn.  */
3309 static bool
msp430_check_plus_not_high_mem(rtx op)3310 msp430_check_plus_not_high_mem (rtx op)
3311 {
3312   if (GET_CODE (op) != PLUS)
3313     return false;
3314   rtx op0 = XEXP (op, 0);
3315   rtx op1 = XEXP (op, 1);
3316   if (SYMBOL_REF_P (op0)
3317       && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM)
3318       && msp430_check_index_not_high_mem (op1))
3319     return true;
3320   return false;
3321 }
3322 
3323 /* Determine whether an RTX is definitely not a MEM referencing an address in
3324    the upper memory region.  Returns true if we've decided the address will be
3325    in the lower memory region, or the RTX is not a MEM.  Returns false
3326    otherwise.
3327    The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
3328    involving a symbol_ref here.  */
3329 bool
msp430_op_not_in_high_mem(rtx op)3330 msp430_op_not_in_high_mem (rtx op)
3331 {
3332   rtx op0;
3333 
3334   if (!TARGET_LARGE || !MEM_P (op))
3335     return true;
3336 
3337   op0 = XEXP (op, 0);
3338 
3339   if (SYMBOL_REF_P (op0) && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM))
3340     /* msp430_encode_section_info decided this mem will be in lower
3341        memory.  */
3342     return true;
3343 
3344   /* Check possibilites for (mem (plus)).
3345      e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2.  */
3346   if (msp430_check_plus_not_high_mem (op0)
3347       || ((GET_CODE (op0) == CONST)
3348 	  && msp430_check_plus_not_high_mem (XEXP (op0, 0))))
3349     return true;
3350 
3351   /* An absolute 16-bit address is allowed.  */
3352   if ((CONST_INT_P (op0) && (IN_RANGE (INTVAL (op0), 0, (1 << 16) - 1))))
3353     return true;
3354 
3355   /* Return false when undecided.  */
3356   return false;
3357 }
3358 
3359 #undef  TARGET_PRINT_OPERAND
3360 #define TARGET_PRINT_OPERAND		msp430_print_operand
3361 
3362 /* A   low 16-bits of int/lower of register pair
3363    B   high 16-bits of int/higher of register pair
3364    C   bits 32-47 of a 64-bit value/reg 3 of a DImode value
3365    D   bits 48-63 of a 64-bit value/reg 4 of a DImode value
3366    H   like %B (for backwards compatibility)
3367    I   inverse of value
3368    J   an integer without a # prefix
3369    L   like %A (for backwards compatibility)
3370    O   offset of the top of the stack
3371    Q   like X but generates an A postfix
3372    R   inverse of condition code, unsigned.
3373    X   X instruction postfix in large mode
3374    Y   value - 4
3375    Z   value - 1
3376    b   .B or .W or .A, depending upon the mode
3377    p   bit position
3378    r   inverse of condition code
3379    x   like X but only for pointers.  */
3380 
3381 static void
msp430_print_operand(FILE * file,rtx op,int letter)3382 msp430_print_operand (FILE * file, rtx op, int letter)
3383 {
3384   rtx addr;
3385 
3386   /* We can't use c, n, a, or l.  */
3387   switch (letter)
3388     {
3389     case 'Z':
3390       gcc_assert (CONST_INT_P (op));
3391       /* Print the constant value, less one.  */
3392       fprintf (file, "#%ld", INTVAL (op) - 1);
3393       return;
3394     case 'Y':
3395       gcc_assert (CONST_INT_P (op));
3396       /* Print the constant value, less four.  */
3397       fprintf (file, "#%ld", INTVAL (op) - 4);
3398       return;
3399     case 'I':
3400       if (GET_CODE (op) == CONST_INT)
3401 	{
3402 	  /* Inverse of constants */
3403 	  int i = INTVAL (op);
3404 	  fprintf (file, "%d", ~i);
3405 	  return;
3406 	}
3407       op = XEXP (op, 0);
3408       break;
3409     case 'r': /* Conditional jump where the condition is reversed.  */
3410       switch (GET_CODE (op))
3411 	{
3412 	case EQ: fprintf (file, "NE"); break;
3413 	case NE: fprintf (file, "EQ"); break;
3414 	case GEU: fprintf (file, "LO"); break;
3415 	case LTU: fprintf (file, "HS"); break;
3416 	case GE: fprintf (file, "L"); break;
3417 	case LT: fprintf (file, "GE"); break;
3418 	  /* Assume these have reversed operands.  */
3419 	case GTU: fprintf (file, "HS"); break;
3420 	case LEU: fprintf (file, "LO"); break;
3421 	case GT: fprintf (file, "GE"); break;
3422 	case LE: fprintf (file, "L"); break;
3423 	default:
3424 	  msp430_print_operand_raw (file, op);
3425 	  break;
3426 	}
3427       return;
3428     case 'R': /* Conditional jump where the operands are reversed.  */
3429       switch (GET_CODE (op))
3430 	{
3431 	case GTU: fprintf (file, "LO"); break;
3432 	case LEU: fprintf (file, "HS"); break;
3433 	case GT: fprintf (file, "L"); break;
3434 	case LE: fprintf (file, "GE"); break;
3435 	default:
3436 	  msp430_print_operand_raw (file, op);
3437 	  break;
3438 	}
3439       return;
3440     case 'p': /* Bit position.  0 == 0x01, 3 = 0x08 etc.  */
3441       gcc_assert (CONST_INT_P (op));
3442       fprintf (file, "#%d", 1 << INTVAL (op));
3443       return;
3444     case 'b':
3445       switch (GET_MODE (op))
3446 	{
3447 	case E_QImode: fprintf (file, ".B"); return;
3448 	case E_HImode: fprintf (file, ".W"); return;
3449 	case E_PSImode: fprintf (file, ".A"); return;
3450 	case E_SImode: fprintf (file, ".A"); return;
3451 	default:
3452 	  return;
3453 	}
3454     case 'A':
3455     case 'L': /* Low half.  */
3456       switch (GET_CODE (op))
3457 	{
3458 	case MEM:
3459 	  op = adjust_address (op, Pmode, 0);
3460 	  break;
3461 	case REG:
3462 	  break;
3463 	case CONST_INT:
3464 	  op = GEN_INT (INTVAL (op) & 0xffff);
3465 	  letter = 0;
3466 	  break;
3467 	default:
3468 	  /* If you get here, figure out a test case :-) */
3469 	  gcc_unreachable ();
3470 	}
3471       break;
3472     case 'B':
3473     case 'H': /* high half */
3474       switch (GET_CODE (op))
3475 	{
3476 	case MEM:
3477 	  /* We don't need to adjust the address for post_inc.  */
3478 	  op = adjust_address (op, Pmode,
3479 			       (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 2);
3480 	  break;
3481 	case REG:
3482 	  op = gen_rtx_REG (Pmode, REGNO (op) + 1);
3483 	  break;
3484 	case CONST_INT:
3485 	  op = GEN_INT (INTVAL (op) >> 16);
3486 	  letter = 0;
3487 	  break;
3488 	default:
3489 	  /* If you get here, figure out a test case :-) */
3490 	  gcc_unreachable ();
3491 	}
3492       break;
3493     case 'C':
3494       switch (GET_CODE (op))
3495 	{
3496 	case MEM:
3497 	  op = adjust_address (op, Pmode,
3498 			       (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 4);
3499 	  break;
3500 	case REG:
3501 	  op = gen_rtx_REG (Pmode, REGNO (op) + 2);
3502 	  break;
3503 	case CONST_INT:
3504 	  op = GEN_INT ((long long) INTVAL (op) >> 32);
3505 	  letter = 0;
3506 	  break;
3507 	default:
3508 	  /* If you get here, figure out a test case :-) */
3509 	  gcc_unreachable ();
3510 	}
3511       break;
3512     case 'D':
3513       switch (GET_CODE (op))
3514 	{
3515 	case MEM:
3516 	  op = adjust_address (op, Pmode,
3517 			       (GET_CODE (XEXP (op, 0)) == POST_INC) ? 0 : 6);
3518 	  break;
3519 	case REG:
3520 	  op = gen_rtx_REG (Pmode, REGNO (op) + 3);
3521 	  break;
3522 	case CONST_INT:
3523 	  op = GEN_INT ((long long) INTVAL (op) >> 48);
3524 	  letter = 0;
3525 	  break;
3526 	default:
3527 	  /* If you get here, figure out a test case :-) */
3528 	  gcc_unreachable ();
3529 	}
3530       break;
3531 
3532     case 'X':
3533       /* This is used to turn, for example, an ADD opcode into an ADDX
3534 	 opcode when we're using 20-bit addresses.
3535 	 This can be used for insns which have only one operand which might be
3536 	 a mem.
3537 	 If an insn has two different operands which could be memory operands,
3538 	 then the "Yx" constraint must be used to determine if the X suffix is
3539 	 required by checking both operands.  */
3540       if (GET_MODE (op) == PSImode
3541 	  || !msp430_op_not_in_high_mem (op))
3542 	fprintf (file, "X");
3543       return;
3544 
3545     case 'x':
3546       /* Similarly, but only for PSImodes.  BIC, and other insn patterns using
3547 	 the QHI mode iterator (which includes, QI, HI, and PSImode) use
3548 	 this.  */
3549       if (GET_MODE (op) == PSImode)
3550 	fprintf (file, "X");
3551       return;
3552 
3553     case 'Q':
3554       /* Likewise, for BR -> BRA.  */
3555       if (TARGET_LARGE)
3556 	fprintf (file, "A");
3557       return;
3558 
3559     case 'O':
3560       /* Computes the offset to the top of the stack for the current frame.
3561 	 This has to be done here rather than in, say, msp430_expand_builtin()
3562 	 because builtins are expanded before the frame layout is
3563 	 determined.  */
3564       fprintf (file, "%d",
3565 	       msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
3566 						  STACK_POINTER_REGNUM)
3567 	       - (TARGET_LARGE ? 4 : 2));
3568       return;
3569 
3570     case 'J':
3571       gcc_assert (GET_CODE (op) == CONST_INT);
3572     case 0:
3573       break;
3574     default:
3575       output_operand_lossage ("invalid operand prefix");
3576       return;
3577     }
3578 
3579   switch (GET_CODE (op))
3580     {
3581     case REG:
3582       msp430_print_operand_raw (file, op);
3583       break;
3584 
3585     case MEM:
3586       addr = XEXP (op, 0);
3587       msp430_print_operand_addr (file, GET_MODE (op), addr);
3588       break;
3589 
3590     case CONST:
3591       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
3592 	{
3593 	  op = XEXP (op, 0);
3594 	  switch (INTVAL (XEXP (op, 2)))
3595 	    {
3596 	    case 0:
3597 	      fprintf (file, "#lo (");
3598 	      msp430_print_operand_raw (file, XEXP (op, 0));
3599 	      fprintf (file, ")");
3600 	      break;
3601 
3602 	    case 16:
3603 	      fprintf (file, "#hi (");
3604 	      msp430_print_operand_raw (file, XEXP (op, 0));
3605 	      fprintf (file, ")");
3606 	      break;
3607 
3608 	    default:
3609 	      output_operand_lossage ("invalid zero extract");
3610 	      break;
3611 	    }
3612 	  break;
3613 	}
3614       /* Fall through.  */
3615     case CONST_INT:
3616     case SYMBOL_REF:
3617     case LABEL_REF:
3618       if (letter == 0)
3619 	fprintf (file, "#");
3620       msp430_print_operand_raw (file, op);
3621       break;
3622 
3623     case EQ: fprintf (file, "EQ"); break;
3624     case NE: fprintf (file, "NE"); break;
3625     case GEU: fprintf (file, "HS"); break;
3626     case LTU: fprintf (file, "LO"); break;
3627     case GE: fprintf (file, "GE"); break;
3628     case LT: fprintf (file, "L"); break;
3629 
3630     default:
3631       print_rtl (file, op);
3632       break;
3633     }
3634 }
3635 
3636 
3637 /* Frame stuff.  */
3638 
3639 rtx
msp430_return_addr_rtx(int count)3640 msp430_return_addr_rtx (int count)
3641 {
3642   int ra_size;
3643   if (count)
3644     return NULL_RTX;
3645 
3646   ra_size = TARGET_LARGE ? 4 : 2;
3647   if (crtl->args.pretend_args_size)
3648     ra_size += 2;
3649 
3650   return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx,
3651 					   GEN_INT (- ra_size)));
3652 }
3653 
3654 rtx
msp430_incoming_return_addr_rtx(void)3655 msp430_incoming_return_addr_rtx (void)
3656 {
3657   return gen_rtx_MEM (Pmode, stack_pointer_rtx);
3658 }
3659 
3660 /* If the path to the MSP430-GCC support files has been found by examining
3661    an environment variable (see msp430_check_env_var_for_devices in
3662    msp430-devices.c), or -mdevices-csv-loc=, register this path as an include
3663    directory so the user can #include msp430.h without needing to specify the
3664    path to the support files with -I.  */
3665 void
msp430_register_pre_includes(const char * sysroot ATTRIBUTE_UNUSED,const char * iprefix ATTRIBUTE_UNUSED,int stdinc ATTRIBUTE_UNUSED)3666 msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
3667 			      const char *iprefix ATTRIBUTE_UNUSED,
3668 			      int stdinc ATTRIBUTE_UNUSED)
3669 {
3670   char *include_dir;
3671   if (msp430_devices_csv_loc)
3672     include_dir = xstrdup (msp430_devices_csv_loc);
3673   else if (msp430_check_env_var_for_devices (&include_dir))
3674     return;
3675   include_dir = msp430_dirname (include_dir);
3676 
3677   include_dir = update_path (include_dir, "");
3678   add_path (include_dir, INC_SYSTEM, false, false);
3679 }
3680 
3681 /* Instruction generation stuff.  */
3682 
3683 /* Generate a sequence of instructions to sign-extend an HI
3684    value into an SI value.  Handles the tricky case where
3685    we are overwriting the destination.  */
3686 
3687 const char *
msp430x_extendhisi(rtx * operands)3688 msp430x_extendhisi (rtx * operands)
3689 {
3690   if (REGNO (operands[0]) == REGNO (operands[1]))
3691     /* Low word of dest == source word.  8-byte sequence.  */
3692     return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0";
3693 
3694   if (! msp430x)
3695     /* Note: This sequence is approximately the same length as invoking a helper
3696        function to perform the sign-extension, as in:
3697 
3698        MOV.W  %1, %L0
3699        MOV.W  %1, r12
3700        CALL   __mspabi_srai_15
3701        MOV.W  r12, %H0
3702 
3703        but this version does not involve any function calls or using argument
3704        registers, so it reduces register pressure.  10-byte sequence.  */
3705     return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 "
3706       "{ INV.W\t%H0, %H0";
3707 
3708   if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
3709     /* High word of dest == source word.  6-byte sequence.  */
3710     return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0";
3711 
3712   /* No overlap between dest and source.  8-byte sequence.  */
3713   return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0";
3714 }
3715 
3716 /* Likewise for logical right shifts.  */
3717 const char *
msp430x_logical_shift_right(rtx amount)3718 msp430x_logical_shift_right (rtx amount)
3719 {
3720   /* The MSP430X's logical right shift instruction - RRUM - does
3721      not use an extension word, so we cannot encode a repeat count.
3722      Try various alternatives to work around this.  If the count
3723      is in a register we are stuck, hence the assert.  */
3724   gcc_assert (CONST_INT_P (amount));
3725 
3726   if (INTVAL (amount) <= 0
3727       || INTVAL (amount) >= 16)
3728     return "# nop logical shift.";
3729 
3730   if (INTVAL (amount) > 0
3731       && INTVAL (amount) < 5)
3732     return "rrum.w\t%2, %0"; /* Two bytes.  */
3733 
3734   if (INTVAL (amount) > 4
3735       && INTVAL (amount) < 9)
3736     return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes.  */
3737 
3738   /* First we logically shift right by one.  Now we know
3739      that the top bit is zero and we can use the arithmetic
3740      right shift instruction to perform the rest of the shift.  */
3741   return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes.  */
3742 }
3743 
3744 /* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)).  */
3745 
3746 #undef TARGET_CAN_CHANGE_MODE_CLASS
3747 #define TARGET_CAN_CHANGE_MODE_CLASS msp430_can_change_mode_class
3748 
3749 static bool
msp430_can_change_mode_class(machine_mode from,machine_mode to,reg_class_t)3750 msp430_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t)
3751 {
3752   if ((to == PSImode && from == SImode)
3753       || (to == SImode && from == PSImode)
3754       || (to == DImode && from == PSImode)
3755       || (to == PSImode && from == DImode))
3756     return false;
3757   return true;
3758 }
3759 
3760 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
3761 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
3762 
3763 struct gcc_target targetm = TARGET_INITIALIZER;
3764 
3765 #include "gt-msp430.h"
3766