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