xref: /netbsd-src/external/gpl3/gcc/dist/gcc/config/msp430/msp430.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Subroutines used for code generation on TI MSP430 processors.
2    Copyright (C) 2012-2022 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 (startswith (target_mcu, "msp430i"))
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; "
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; use 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; use 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.cc:
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
is_interrupt_func(tree decl=current_function_decl)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
is_wakeup_func(tree decl=current_function_decl)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
is_naked_func(tree decl=current_function_decl)1821 is_naked_func (tree decl = current_function_decl)
1822 {
1823   return has_attr (ATTR_NAKED, decl);
1824 }
1825 
1826 static inline bool
is_reentrant_func(tree decl=current_function_decl)1827 is_reentrant_func (tree decl = current_function_decl)
1828 {
1829   return has_attr (ATTR_REENT, decl);
1830 }
1831 
1832 static inline bool
is_critical_func(tree decl=current_function_decl)1833 is_critical_func (tree decl = current_function_decl)
1834 {
1835   return has_attr (ATTR_CRIT, decl);
1836 }
1837 
1838 static bool
has_section_name(const char * name,tree decl=current_function_decl)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       || startswith (name, prefix))
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 (startswith (name, lower_prefix))
2483     name += strlen (lower_prefix);
2484   else if (startswith (name, upper_prefix))
2485     name += strlen (upper_prefix);
2486   else if (startswith (name, either_prefix))
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 built-in 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 = startswith (helper_name, "__mspabi_mpy");
3247   /* This function has been used incorrectly if CONST_VARIANTS is TRUE for a
3248      hwmpy function.  */
3249   gcc_assert (!(expand_mpy && const_variants));
3250 
3251   if (arg1mode != VOIDmode && arg2mode != VOIDmode)
3252     /* Modes of arguments must be equal if not constants.  */
3253     gcc_assert (arg1mode == arg2mode);
3254 
3255   if (arg1mode == VOIDmode)
3256     arg1mode = arg0mode;
3257   if (arg2mode == VOIDmode)
3258     arg2mode = arg0mode;
3259 
3260   if (arg1mode == SImode)
3261     {
3262       arg2 = 14;
3263       arg1sz = 2;
3264     }
3265   else if (arg1mode == DImode)
3266     {
3267       arg1 = 8;
3268       arg1sz = 4;
3269       arg2 = 12;
3270     }
3271 
3272   /* Use the "const_variant" of a shift library function if requested.
3273      These are faster, but have larger code size.  */
3274   if (const_variants
3275       && CONST_INT_P (operands[2])
3276       && INTVAL (operands[2]) >= 1
3277       && INTVAL (operands[2]) <= 15)
3278     {
3279       /* Note that the INTVAL is limited in value and length by the conditional
3280 	 above.  */
3281       int len = strlen (helper_name) + 4;
3282       helper_const = (char *) xmalloc (len);
3283       snprintf (helper_const, len, "%s_%d", helper_name,
3284 		(int) INTVAL (operands[2]));
3285     }
3286 
3287   /* Setup the arguments to the helper function.  */
3288   emit_move_insn (gen_rtx_REG (arg1mode, arg1),
3289 		  operands[1]);
3290   if (!helper_const)
3291     emit_move_insn (gen_rtx_REG (arg2mode, arg2),
3292 		    operands[2]);
3293 
3294   if (expand_mpy)
3295     {
3296       if (msp430_use_f5_series_hwmult ())
3297 	fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3298 						     "_f5hw", NULL));
3299       else if (msp430_use_32bit_hwmult ())
3300 	{
3301 	  /* When the arguments are 16-bits, the 16-bit hardware multiplier is
3302 	     used.  */
3303 	  if (arg1mode == HImode)
3304 	    fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3305 							 "_hw", NULL));
3306 	  else
3307 	    fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3308 							 "_hw32", NULL));
3309 	}
3310       else if (msp430_use_16bit_hwmult ())
3311 	fsym = gen_rtx_SYMBOL_REF (VOIDmode, concat (helper_name,
3312 						     "_hw", NULL));
3313       else
3314 	fsym = gen_rtx_SYMBOL_REF (VOIDmode, helper_name);
3315     }
3316   else
3317     fsym = gen_rtx_SYMBOL_REF (VOIDmode,
3318 			       helper_const ? helper_const : helper_name);
3319 
3320   c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), fsym, GEN_INT (0));
3321 
3322   c = emit_call_insn (c);
3323   RTL_CONST_CALL_P (c) = 1;
3324 
3325   /* Add register usage information for the arguments to the call.  */
3326   fusage = NULL;
3327   use_regs (&fusage, arg1, arg1sz);
3328   if (!helper_const)
3329     {
3330       /* If we are expanding a shift, we only need to use the low register
3331 	 for the shift amount.  */
3332       if (!expand_mpy)
3333 	use_regs (&fusage, arg2, 1);
3334       else
3335 	use_regs (&fusage, arg2, arg1sz);
3336     }
3337   add_function_usage_to (c, fusage);
3338 
3339   emit_move_insn (operands[0],
3340 		  /* Return value will always start in R12.  */
3341 		  gen_rtx_REG (arg0mode, 12));
3342 }
3343 
3344 /* Return TRUE if the helper function should be used and FALSE if the shifts
3345    insns should be emitted inline.  */
3346 static bool
use_helper_for_const_shift(machine_mode mode,HOST_WIDE_INT amt)3347 use_helper_for_const_shift (machine_mode mode, HOST_WIDE_INT amt)
3348 {
3349   const int default_inline_shift = 4;
3350   /* We initialize the option to 65 so we know if the user set it or not.  */
3351   int user_set_max_inline = (msp430_max_inline_shift == 65 ? 0 : 1);
3352   int max_inline = (user_set_max_inline ? msp430_max_inline_shift
3353 		    : default_inline_shift);
3354   /* 32-bit shifts are roughly twice as costly as 16-bit shifts so we adjust
3355      the heuristic accordingly.  */
3356   int max_inline_32 = max_inline / 2;
3357 
3358   if (mode == E_DImode)
3359     return true;
3360 
3361   /* Don't use helpers for these modes on 430X, when optimizing for speed, or
3362      when emitting a small number of insns.  */
3363   if ((mode == E_QImode || mode == E_HImode || mode == E_PSImode)
3364       && (msp430x
3365 	  /* If the user set max_inline then we always obey that number.
3366 	     Otherwise we always emit the shifts inline at -O2 and above.  */
3367 	  || amt <= max_inline
3368 	  || (!user_set_max_inline
3369 	      && (optimize >= 2 && !optimize_size))))
3370     return false;
3371 
3372   /* 430 and 430X codegen for SImode shifts is the same.
3373      Set a hard limit of 15 for the number of shifts that will be emitted
3374      inline by default, even at -O2 and above, to prevent code size
3375      explosion.  */
3376   if (mode == E_SImode
3377       && (amt <= max_inline_32
3378 	  || (!user_set_max_inline
3379 	      && (optimize >= 2 && !optimize_size)
3380 	      && amt <= 15)))
3381     return false;
3382 
3383   return true;
3384 }
3385 
3386 /* For shift operations which will use an mspabi helper function, setup the
3387    call to msp430_expand helper.  Return 1 to indicate we have finished with
3388    this insn and invoke "DONE".
3389    Otherwise return 0 to indicate the insn should fallthrough.
3390    Never FAIL.  */
3391 int
msp430_expand_shift(enum rtx_code code,machine_mode mode,rtx * operands)3392 msp430_expand_shift (enum rtx_code code, machine_mode mode, rtx *operands)
3393 {
3394   /* Always use the helper function when the shift amount is not a
3395      constant.  */
3396   if (!CONST_INT_P (operands[2])
3397       || mode == E_DImode
3398       || use_helper_for_const_shift (mode, INTVAL (operands[2])))
3399     {
3400       const char *helper_name = NULL;
3401       /* The const variants of mspabi shifts have significantly larger code
3402 	 size than the generic version, so use the generic version if
3403 	 optimizing for size.  */
3404       bool const_variant = !optimize_size;
3405       switch (mode)
3406 	{
3407 	case E_HImode:
3408 	  helper_name = (code == ASHIFT ? "__mspabi_slli" :
3409 			 (code == ASHIFTRT ? "__mspabi_srai" :
3410 			  (code == LSHIFTRT ? "__mspabi_srli" :
3411 			   NULL)));
3412 	  break;
3413 	case E_PSImode:
3414 	  helper_name = (code == ASHIFT ? "__gnu_mspabi_sllp" :
3415 			 (code == ASHIFTRT ? "__gnu_mspabi_srap" :
3416 			  (code == LSHIFTRT ? "__gnu_mspabi_srlp" :
3417 			   NULL)));
3418 	  /* No const variant for PSImode shifts FIXME.  */
3419 	  const_variant = false;
3420 	  break;
3421 	case E_SImode:
3422 	  helper_name = (code == ASHIFT ? "__mspabi_slll" :
3423 			 (code == ASHIFTRT ? "__mspabi_sral" :
3424 			  (code == LSHIFTRT ? "__mspabi_srll" :
3425 			   NULL)));
3426 	  break;
3427 	case E_DImode:
3428 	  helper_name = (code == ASHIFT ? "__mspabi_sllll" :
3429 			 (code == ASHIFTRT ? "__mspabi_srall" :
3430 			  (code == LSHIFTRT ? "__mspabi_srlll" :
3431 			   NULL)));
3432 	  /* No const variant for DImode shifts.  */
3433 	  const_variant = false;
3434 	  break;
3435 	default:
3436 	  gcc_unreachable ();
3437 	  break;
3438 	}
3439       gcc_assert (helper_name);
3440       msp430_expand_helper (operands, helper_name, const_variant);
3441       return 1;
3442     }
3443   /* When returning 0, there must be an insn to match the RTL pattern
3444      otherwise there will be an unrecognizeable insn.  */
3445   return 0;
3446 }
3447 
3448 /* Helper function to emit a sequence of shift instructions.  The amount of
3449    shift instructions to emit is in OPERANDS[2].
3450    For 430 we output copies of identical inline shifts for all modes.
3451    For 430X it is inneficient to do so for any modes except SI and DI, since we
3452    can make use of R*M insns or RPT with 430X insns, so this function is only
3453    used for SImode in that case.  */
3454 int
msp430_output_asm_shift_insns(enum rtx_code code,machine_mode mode,rtx * operands,bool return_length)3455 msp430_output_asm_shift_insns (enum rtx_code code, machine_mode mode,
3456 			       rtx *operands, bool return_length)
3457 {
3458   int i;
3459   int amt;
3460   int max_shift = GET_MODE_BITSIZE (mode) - 1;
3461   int length = 0;
3462 
3463   gcc_assert (CONST_INT_P (operands[2]));
3464   amt = INTVAL (operands[2]);
3465 
3466   if (amt == 0 || amt > max_shift)
3467     {
3468       if (return_length)
3469 	return 0;
3470       switch (code)
3471 	{
3472 	case ASHIFT:
3473 	  output_asm_insn ("# ignored undefined behaviour left shift "
3474 			   "of %1 by %2", operands);
3475 	  break;
3476 	case ASHIFTRT:
3477 	  output_asm_insn ("# ignored undefined behaviour arithmetic right "
3478 			   "shift of %1 by %2", operands);
3479 	  break;
3480 	case LSHIFTRT:
3481 	  output_asm_insn ("# ignored undefined behaviour logical right shift "
3482 			   "of %1 by %2", operands);
3483 	  break;
3484 	default:
3485 	  gcc_unreachable ();
3486 	}
3487       return 0;
3488     }
3489 
3490   if (code == ASHIFT)
3491     {
3492       if (!msp430x && mode == HImode)
3493 	{
3494 	  if (return_length)
3495 	    length = 2 + (MEM_P (operands[0]) ? 2 : 0);
3496 	  else
3497 	    for (i = 0; i < amt; i++)
3498 	      output_asm_insn ("RLA.W\t%0", operands);
3499 	}
3500       else if (mode == SImode)
3501 	{
3502 	  if (return_length)
3503 	    length = 4 + (MEM_P (operands[0]) ? 4 : 0)
3504 	      + (4 * msp430x_insn_required (operands[0]));
3505 	  else
3506 	    for (i = 0; i < amt; i++)
3507 	      output_asm_insn ("RLA%X0.W\t%L0 { RLC%X0.W\t%H0", operands);
3508 	}
3509       else
3510 	/* Catch unhandled cases.  */
3511 	gcc_unreachable ();
3512     }
3513   else if (code == ASHIFTRT)
3514     {
3515       if (!msp430x && mode == HImode)
3516 	{
3517 	  if (return_length)
3518 	    length = 2 + (MEM_P (operands[0]) ? 2 : 0);
3519 	  else
3520 	    for (i = 0; i < amt; i++)
3521 	      output_asm_insn ("RRA.W\t%0", operands);
3522 	}
3523       else if (mode == SImode)
3524 	{
3525 	  if (return_length)
3526 	    length = 4 + (MEM_P (operands[0]) ? 4 : 0)
3527 	      + (4 * msp430x_insn_required (operands[0]));
3528 	  else
3529 	    for (i = 0; i < amt; i++)
3530 	      output_asm_insn ("RRA%X0.W\t%H0 { RRC%X0.W\t%L0", operands);
3531 	}
3532       else
3533 	gcc_unreachable ();
3534     }
3535   else if (code == LSHIFTRT)
3536     {
3537       if (!msp430x && mode == HImode)
3538 	{
3539 	  if (return_length)
3540 	    length = 4 + (MEM_P (operands[0]) ? 2 : 0);
3541 	  else
3542 	    for (i = 0; i < amt; i++)
3543 	      output_asm_insn ("CLRC { RRC.W\t%0", operands);
3544 	}
3545       else if (mode == SImode)
3546 	{
3547 	  if (return_length)
3548 	    length = 6 + (MEM_P (operands[0]) ? 4 : 0)
3549 	      + (4 * msp430x_insn_required (operands[0]));
3550 	  else
3551 	    for (i = 0; i < amt; i++)
3552 	      output_asm_insn ("CLRC { RRC%X0.W\t%H0 { RRC%X0.W\t%L0",
3553 			       operands);
3554 	}
3555       /* FIXME: Why doesn't "RRUX.W\t%H0 { RRC%X0.W\t%L0" work for msp430x?
3556 	 It causes execution timeouts e.g. pr41963.c.  */
3557 #if 0
3558       else if (msp430x && mode == SImode)
3559 	{
3560 	  if (return_length)
3561 	    length = 2;
3562 	  else
3563 	    for (i = 0; i < amt; i++)
3564 	      output_asm_insn ("RRUX.W\t%H0 { RRC%X0.W\t%L0", operands);
3565 	}
3566 #endif
3567       else
3568 	gcc_unreachable ();
3569     }
3570   return length * amt;
3571 }
3572 
3573 /* Called by cbranch<mode>4 to coerce operands into usable forms.  */
3574 void
msp430_fixup_compare_operands(machine_mode my_mode,rtx * operands)3575 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands)
3576 {
3577   /* constants we're looking for, not constants which are allowed.  */
3578   int const_op_idx = 1;
3579 
3580   if (msp430_reversible_cmp_operator (operands[0], VOIDmode))
3581     const_op_idx = 2;
3582 
3583   if (GET_CODE (operands[const_op_idx]) != REG
3584       && GET_CODE (operands[const_op_idx]) != MEM)
3585     operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]);
3586 }
3587 
3588 /* Simplify_gen_subreg() doesn't handle memory references the way we
3589    need it to below, so we use this function for when we must get a
3590    valid subreg in a "natural" state.  */
3591 rtx
msp430_subreg(machine_mode mode,rtx r,machine_mode omode,int byte)3592 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte)
3593 {
3594   rtx rv;
3595   gcc_assert (mode == HImode);
3596 
3597   if (GET_CODE (r) == SUBREG
3598       && SUBREG_BYTE (r) == 0)
3599     {
3600       rtx ireg = SUBREG_REG (r);
3601       machine_mode imode = GET_MODE (ireg);
3602 
3603       /* special case for (HI (SI (PSI ...), 0)) */
3604       if (imode == PSImode
3605 	  && mode == HImode
3606 	  && byte == 0)
3607 	rv = gen_rtx_SUBREG (mode, ireg, byte);
3608       else
3609 	rv = simplify_gen_subreg (mode, ireg, imode, byte);
3610     }
3611   else if (GET_CODE (r) == MEM)
3612     {
3613       /* When byte == 2, we can be certain that we were already called with an
3614 	 identical rtx with byte == 0.  So we don't need to do anything to
3615 	 get a 2 byte offset of a (mem (post_inc)) rtx, since the address has
3616 	 already been offset by the post_inc itself.  */
3617       if (GET_CODE (XEXP (r, 0)) == POST_INC && byte == 2)
3618 	byte = 0;
3619       rv = adjust_address (r, mode, byte);
3620     }
3621   else if (GET_CODE (r) == SYMBOL_REF
3622 	   && (byte == 0 || byte == 2)
3623 	   && mode == HImode)
3624     {
3625       rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte));
3626       rv = gen_rtx_CONST (HImode, r);
3627     }
3628   else
3629     rv = simplify_gen_subreg (mode, r, omode, byte);
3630 
3631   if (!rv)
3632     gcc_unreachable ();
3633 
3634   return rv;
3635 }
3636 
3637 int
msp430_split_addsi(rtx * operands)3638 msp430_split_addsi (rtx *operands)
3639 {
3640   operands[3] = msp430_subreg (HImode, operands[0], SImode, 0);
3641   operands[4] = msp430_subreg (HImode, operands[1], SImode, 0);
3642   operands[5] = msp430_subreg (HImode, operands[2], SImode, 0);
3643   operands[6] = msp430_subreg (HImode, operands[0], SImode, 2);
3644   operands[7] = msp430_subreg (HImode, operands[1], SImode, 2);
3645   operands[8] = msp430_subreg (HImode, operands[2], SImode, 2);
3646 
3647   /* BZ 64160: Do not use this splitter when the dest partially overlaps the
3648      source.  */
3649   if (reg_overlap_mentioned_p (operands[3], operands[7])
3650       || reg_overlap_mentioned_p (operands[3], operands[8]))
3651     return 1;
3652 
3653   if (GET_CODE (operands[5]) == CONST_INT)
3654     operands[9] = GEN_INT (INTVAL (operands[5]) & 0xffff);
3655   /* Handle post_inc, for example:
3656      (set (reg:SI)
3657 	  (plus:SI (reg:SI)
3658 		   (mem:SI (post_inc:PSI (reg:PSI))))).  */
3659   else if (MEM_P (operands[5]) && GET_CODE (XEXP (operands[5], 0)) == POST_INC)
3660     {
3661       /* Strip out the post_inc from (mem (post_inc (reg))).  */
3662       operands[9] = XEXP (XEXP (operands[5], 0), 0);
3663       operands[9] = gen_rtx_MEM (HImode, operands[9]);
3664       /* Then zero extend as normal.  */
3665       operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[9]);
3666     }
3667   else
3668     operands[9] = gen_rtx_ZERO_EXTEND (SImode, operands[5]);
3669   return 0;
3670 }
3671 
3672 /* Called by movsi_x to generate the HImode operands.  */
3673 void
msp430_split_movsi(rtx * operands)3674 msp430_split_movsi (rtx *operands)
3675 {
3676   rtx op00, op02, op10, op12;
3677 
3678   op00 = msp430_subreg (HImode, operands[0], SImode, 0);
3679   op02 = msp430_subreg (HImode, operands[0], SImode, 2);
3680 
3681   if (GET_CODE (operands[1]) == CONST
3682       || GET_CODE (operands[1]) == SYMBOL_REF)
3683     {
3684       op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
3685 				   GEN_INT (0));
3686       op10 = gen_rtx_CONST (HImode, op10);
3687       op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
3688 				   GEN_INT (16));
3689       op12 = gen_rtx_CONST (HImode, op12);
3690     }
3691   else
3692     {
3693       op10 = msp430_subreg (HImode, operands[1], SImode, 0);
3694       op12 = msp430_subreg (HImode, operands[1], SImode, 2);
3695     }
3696 
3697   if (rtx_equal_p (operands[0], operands[1]))
3698     {
3699       operands[2] = op02;
3700       operands[4] = op12;
3701       operands[3] = op00;
3702       operands[5] = op10;
3703     }
3704   else if (rtx_equal_p (op00, op12)
3705 	   /* Catch the case where we are loading (rN, rN+1) from mem (rN).  */
3706 	   || (REG_P (op00) && reg_mentioned_p (op00, op10))
3707 	   /* Or storing (rN) into mem (rN).  */
3708 	   || (REG_P (op10) && reg_mentioned_p (op10, op00)))
3709     {
3710       operands[2] = op02;
3711       operands[4] = op12;
3712       operands[3] = op00;
3713       operands[5] = op10;
3714     }
3715   else
3716     {
3717       operands[2] = op00;
3718       operands[4] = op10;
3719       operands[3] = op02;
3720       operands[5] = op12;
3721     }
3722 }
3723 
3724 
3725 /* The MSPABI specifies the names of various helper functions, many of
3726    which are compatible with GCC's helpers.  This table maps the GCC
3727    name to the MSPABI name.  */
3728 static const struct
3729 {
3730   char const * const gcc_name;
3731   char const * const ti_name;
3732 }
3733 helper_function_name_mappings[] =
3734   {
3735     /* Floating point to/from integer conversions.  */
3736     { "__truncdfsf2", "__mspabi_cvtdf" },
3737     { "__extendsfdf2", "__mspabi_cvtfd" },
3738     { "__fixdfhi", "__mspabi_fixdi" },
3739     { "__fixdfsi", "__mspabi_fixdli" },
3740     { "__fixdfdi", "__mspabi_fixdlli" },
3741     { "__fixunsdfhi", "__mspabi_fixdu" },
3742     { "__fixunsdfsi", "__mspabi_fixdul" },
3743     { "__fixunsdfdi", "__mspabi_fixdull" },
3744     { "__fixsfhi", "__mspabi_fixfi" },
3745     { "__fixsfsi", "__mspabi_fixfli" },
3746     { "__fixsfdi", "__mspabi_fixflli" },
3747     { "__fixunsfhi", "__mspabi_fixfu" },
3748     { "__fixunsfsi", "__mspabi_fixful" },
3749     { "__fixunsfdi", "__mspabi_fixfull" },
3750     { "__floathisf", "__mspabi_fltif" },
3751     { "__floatsisf", "__mspabi_fltlif" },
3752     { "__floatdisf", "__mspabi_fltllif" },
3753     { "__floathidf", "__mspabi_fltid" },
3754     { "__floatsidf", "__mspabi_fltlid" },
3755     { "__floatdidf", "__mspabi_fltllid" },
3756     { "__floatunhisf", "__mspabi_fltuf" },
3757     { "__floatunsisf", "__mspabi_fltulf" },
3758     { "__floatundisf", "__mspabi_fltullf" },
3759     { "__floatunhidf", "__mspabi_fltud" },
3760     { "__floatunsidf", "__mspabi_fltuld" },
3761     { "__floatundidf", "__mspabi_fltulld" },
3762 
3763     /* Floating point comparisons.  */
3764     /* GCC uses individual functions for each comparison, TI uses one
3765        compare <=> function.  */
3766 
3767     /* Floating point arithmetic.  */
3768     { "__adddf3", "__mspabi_addd" },
3769     { "__addsf3", "__mspabi_addf" },
3770     { "__divdf3", "__mspabi_divd" },
3771     { "__divsf3", "__mspabi_divf" },
3772     { "__muldf3", "__mspabi_mpyd" },
3773     { "__mulsf3", "__mspabi_mpyf" },
3774     { "__subdf3", "__mspabi_subd" },
3775     { "__subsf3", "__mspabi_subf" },
3776     /* GCC does not use helper functions for negation.  */
3777 
3778     /* Integer multiply, divide, remainder.  */
3779     { "__mulhi3", "__mspabi_mpyi" },
3780     { "__mulsi3", "__mspabi_mpyl" },
3781     { "__muldi3", "__mspabi_mpyll" },
3782 #if 0
3783     /* Clarify signed vs unsigned first.  */
3784     { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
3785 					   (yet?) */
3786     { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
3787 					    (yet?) */
3788 #endif
3789 
3790     { "__divhi3", "__mspabi_divi" },
3791     { "__divsi3", "__mspabi_divli" },
3792     { "__divdi3", "__mspabi_divlli" },
3793     { "__udivhi3", "__mspabi_divu" },
3794     { "__udivsi3", "__mspabi_divul" },
3795     { "__udivdi3", "__mspabi_divull" },
3796     { "__modhi3", "__mspabi_remi" },
3797     { "__modsi3", "__mspabi_remli" },
3798     { "__moddi3", "__mspabi_remlli" },
3799     { "__umodhi3", "__mspabi_remu" },
3800     { "__umodsi3", "__mspabi_remul" },
3801     { "__umoddi3", "__mspabi_remull" },
3802 
3803     /* Bitwise operations.  */
3804     /* Rotation - no rotation support yet.  */
3805     /* Logical left shift - gcc already does these itself.  */
3806     /* Arithmetic left shift - gcc already does these itself.  */
3807     /* Arithmetic right shift - gcc already does these itself.  */
3808 
3809     { NULL, NULL }
3810   };
3811 
3812 /* Returns true if the current MCU supports an F5xxx series
3813    hardware multiper.  */
3814 
3815 bool
msp430_use_f5_series_hwmult(void)3816 msp430_use_f5_series_hwmult (void)
3817 {
3818   static const char * cached_match = NULL;
3819   static bool cached_result;
3820 
3821   if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
3822     return true;
3823 
3824   if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3825     return false;
3826 
3827   if (target_mcu == cached_match)
3828     return cached_result;
3829 
3830   cached_match = target_mcu;
3831 
3832   if (strncasecmp (target_mcu, "msp430f5", 8) == 0)
3833     return cached_result = true;
3834   if (strncasecmp (target_mcu, "msp430fr5", 9) == 0)
3835     return cached_result = true;
3836   if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
3837     return cached_result = true;
3838 
3839   msp430_extract_mcu_data (target_mcu);
3840 
3841   if (extracted_mcu_data.name != NULL)
3842     return cached_result = extracted_mcu_data.hwmpy == 8;
3843 
3844   return cached_result = false;
3845 }
3846 
3847 /* Returns true if the current MCU has a second generation
3848    32-bit hardware multiplier.  */
3849 
3850 static bool
msp430_use_32bit_hwmult(void)3851 msp430_use_32bit_hwmult (void)
3852 {
3853   static const char * cached_match = NULL;
3854   static bool cached_result;
3855 
3856   if (msp430_hwmult_type == MSP430_HWMULT_LARGE)
3857     return true;
3858 
3859   if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3860     return false;
3861 
3862   if (target_mcu == cached_match)
3863     return cached_result;
3864 
3865   cached_match = target_mcu;
3866 
3867   msp430_extract_mcu_data (target_mcu);
3868   if (extracted_mcu_data.name != NULL)
3869     return cached_result = extracted_mcu_data.hwmpy == 4;
3870 
3871   return cached_result = false;
3872 }
3873 
3874 /* Returns true if the current MCU has a first generation
3875    16-bit hardware multiplier.  */
3876 
3877 static bool
msp430_use_16bit_hwmult(void)3878 msp430_use_16bit_hwmult (void)
3879 {
3880   static const char * cached_match = NULL;
3881   static bool	      cached_result;
3882 
3883   if (msp430_hwmult_type == MSP430_HWMULT_SMALL)
3884     return true;
3885 
3886   if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO)
3887     return false;
3888 
3889   if (target_mcu == cached_match)
3890     return cached_result;
3891 
3892   cached_match = target_mcu;
3893 
3894   msp430_extract_mcu_data (target_mcu);
3895   if (extracted_mcu_data.name != NULL)
3896     return cached_result = (extracted_mcu_data.hwmpy == 1
3897 			    || extracted_mcu_data.hwmpy == 2);
3898 
3899   return cached_result = false;
3900 }
3901 
3902 /* Returns true if the current MCU does not have a
3903    hardware multiplier of any kind.  */
3904 
3905 bool
msp430_has_hwmult(void)3906 msp430_has_hwmult (void)
3907 {
3908   static const char * cached_match = NULL;
3909   static bool cached_result;
3910 
3911   if (msp430_hwmult_type == MSP430_HWMULT_NONE)
3912     return false;
3913 
3914   /* TRUE for any other explicit hwmult specified.  */
3915   if (msp430_hwmult_type != MSP430_HWMULT_AUTO)
3916     return true;
3917 
3918   /* Now handle -mhwmult=auto.  */
3919   if (target_mcu == NULL)
3920     return false;
3921 
3922   if (target_mcu == cached_match)
3923     return cached_result;
3924 
3925   cached_match = target_mcu;
3926 
3927   msp430_extract_mcu_data (target_mcu);
3928   if (extracted_mcu_data.name != NULL)
3929     return cached_result = extracted_mcu_data.hwmpy != 0;
3930 
3931   /* If we do not recognise the MCU name, we assume that it does not support
3932      any kind of hardware multiply - this is the safest assumption to make.  */
3933   return cached_result = false;
3934 }
3935 
3936 /* This function does the same as the default, but it will replace GCC
3937    function names with the MSPABI-specified ones.  */
3938 
3939 void
msp430_output_labelref(FILE * file,const char * name)3940 msp430_output_labelref (FILE *file, const char *name)
3941 {
3942   int i;
3943 
3944   for (i = 0; helper_function_name_mappings[i].gcc_name; i++)
3945     if (strcmp (helper_function_name_mappings[i].gcc_name, name) == 0)
3946       {
3947 	name = helper_function_name_mappings[i].ti_name;
3948 	break;
3949       }
3950 
3951   if (user_label_prefix[0] != 0)
3952     fputs (user_label_prefix, file);
3953 
3954   fputs (name, file);
3955 }
3956 
3957 /* Common code for msp430_print_operand...  */
3958 
3959 static void
msp430_print_operand_raw(FILE * file,rtx op)3960 msp430_print_operand_raw (FILE * file, rtx op)
3961 {
3962   HOST_WIDE_INT i;
3963 
3964   switch (GET_CODE (op))
3965     {
3966     case REG:
3967       fprintf (file, "%s", reg_names[REGNO (op)]);
3968       break;
3969 
3970     case CONST_INT:
3971       i = INTVAL (op);
3972       if (TARGET_ASM_HEX)
3973 	fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
3974       else
3975 	fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
3976       break;
3977 
3978     case CONST:
3979     case PLUS:
3980     case MINUS:
3981     case SYMBOL_REF:
3982     case LABEL_REF:
3983       output_addr_const (file, op);
3984       break;
3985 
3986     default:
3987       print_rtl (file, op);
3988       break;
3989     }
3990 }
3991 
3992 #undef  TARGET_ASM_ALIGNED_PSI_OP
3993 #define TARGET_ASM_ALIGNED_PSI_OP "\t.long\t"
3994 #undef  TARGET_ASM_UNALIGNED_PSI_OP
3995 #define TARGET_ASM_UNALIGNED_PSI_OP TARGET_ASM_ALIGNED_PSI_OP
3996 
3997 #undef  TARGET_PRINT_OPERAND_ADDRESS
3998 #define TARGET_PRINT_OPERAND_ADDRESS	msp430_print_operand_addr
3999 
4000 /* Output to stdio stream FILE the assembler syntax for an
4001    instruction operand that is a memory reference whose address
4002    is ADDR.  */
4003 
4004 static void
msp430_print_operand_addr(FILE * file,machine_mode,rtx addr)4005 msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
4006 {
4007   switch (GET_CODE (addr))
4008     {
4009     case PLUS:
4010       msp430_print_operand_raw (file, XEXP (addr, 1));
4011       gcc_assert (REG_P (XEXP (addr, 0)));
4012       fprintf (file, "(%s)", reg_names[REGNO (XEXP (addr, 0))]);
4013       return;
4014 
4015     case REG:
4016       fprintf (file, "@");
4017       break;
4018 
4019     case POST_INC:
4020       fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
4021       return;
4022 
4023     case CONST:
4024     case CONST_INT:
4025     case SYMBOL_REF:
4026     case LABEL_REF:
4027       fprintf (file, "&");
4028       break;
4029 
4030     default:
4031       break;
4032     }
4033 
4034   msp430_print_operand_raw (file, addr);
4035 }
4036 
4037 /* We can only allow signed 15-bit indexes i.e. +/-32K.  */
4038 static bool
msp430_check_index_not_high_mem(rtx op)4039 msp430_check_index_not_high_mem (rtx op)
4040 {
4041   if (CONST_INT_P (op)
4042       && IN_RANGE (INTVAL (op), HOST_WIDE_INT_M1U << 15, (1 << 15) - 1))
4043     return true;
4044   return false;
4045 }
4046 
4047 /* If this returns true, we don't need a 430X insn.  */
4048 static bool
msp430_check_plus_not_high_mem(rtx op)4049 msp430_check_plus_not_high_mem (rtx op)
4050 {
4051   if (GET_CODE (op) != PLUS)
4052     return false;
4053   rtx op0 = XEXP (op, 0);
4054   rtx op1 = XEXP (op, 1);
4055   if (SYMBOL_REF_P (op0)
4056       && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM)
4057       && msp430_check_index_not_high_mem (op1))
4058     return true;
4059   return false;
4060 }
4061 
4062 /* Determine whether an RTX is definitely not a MEM referencing an address in
4063    the upper memory region.  Returns true if we've decided the address will be
4064    in the lower memory region, or the RTX is not a MEM.  Returns false
4065    otherwise.
4066    The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
4067    involving a symbol_ref here.  */
4068 bool
msp430_op_not_in_high_mem(rtx op)4069 msp430_op_not_in_high_mem (rtx op)
4070 {
4071   rtx op0;
4072 
4073   if (!TARGET_LARGE || !MEM_P (op))
4074     return true;
4075 
4076   op0 = XEXP (op, 0);
4077 
4078   if (SYMBOL_REF_P (op0) && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM))
4079     /* msp430_encode_section_info decided this mem will be in lower
4080        memory.  */
4081     return true;
4082 
4083   /* Check possibilites for (mem (plus)).
4084      e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2.  */
4085   if (msp430_check_plus_not_high_mem (op0)
4086       || ((GET_CODE (op0) == CONST)
4087 	  && msp430_check_plus_not_high_mem (XEXP (op0, 0))))
4088     return true;
4089 
4090   /* An absolute 16-bit address is allowed.  */
4091   if ((CONST_INT_P (op0) && (IN_RANGE (INTVAL (op0), 0, (1 << 16) - 1))))
4092     return true;
4093 
4094   /* Return false when undecided.  */
4095   return false;
4096 }
4097 
4098 /* Based on the operand OP, is a 430X insn required to handle it?
4099    There are only 3 conditions for which a 430X insn is required:
4100    - PSImode operand
4101    - memory reference to a symbol which could be in upper memory
4102      (so its address is > 0xFFFF)
4103    - absolute address which has VOIDmode, i.e. (mem:HI (const_int))
4104    Use a 430 insn if none of these conditions are true.  */
4105 bool
msp430x_insn_required(rtx op)4106 msp430x_insn_required (rtx op)
4107 {
4108   return (GET_MODE (op) == PSImode
4109 	  || !msp430_op_not_in_high_mem (op));
4110 }
4111 
4112 #undef  TARGET_PRINT_OPERAND
4113 #define TARGET_PRINT_OPERAND		msp430_print_operand
4114 
4115 /* A   Select low 16-bits of the constant/register/memory operand.
4116    B   Select high 16-bits of the constant/register/memory
4117        operand.
4118    C   Select bits 32-47 of the constant/register/memory operand.
4119    D   Select bits 48-63 of the constant/register/memory operand.
4120    H   Equivalent to @code{B} (for backwards compatibility).
4121    I   Print the inverse (logical @code{NOT}) of the constant
4122        value.
4123    J   Print an integer without a @code{#} prefix.
4124    L   Equivalent to @code{A} (for backwards compatibility).
4125    O   Offset of the current frame from the top of the stack.
4126    Q   Use the @code{A} instruction postfix.
4127    R   Inverse of condition code, for unsigned comparisons.
4128    W   Subtract 16 from the constant value.
4129    X   Use the @code{X} instruction postfix.
4130    Y   Subtract 4 from the constant value.
4131    Z   Subtract 1 from the constant value.
4132    b   Append @code{.B}, @code{.W} or @code{.A} to the
4133        instruction, depending on the mode.
4134    d   Offset 1 byte of a memory reference or constant value.
4135    e   Offset 3 bytes of a memory reference or constant value.
4136    f   Offset 5 bytes of a memory reference or constant value.
4137    g   Offset 7 bytes of a memory reference or constant value.
4138    p   Print the value of 2, raised to the power of the given
4139        constant.  Used to select the specified bit position.
4140    r   Inverse of condition code, for signed comparisons.
4141    x   Equivialent to @code{X}, but only for pointers.  */
4142 
4143 static void
msp430_print_operand(FILE * file,rtx op,int letter)4144 msp430_print_operand (FILE * file, rtx op, int letter)
4145 {
4146   rtx addr;
4147   /* These are used by the 'A', 'B', 'C', 'D', 'd', 'e', 'f' and 'g' modifiers
4148      to describe how to process the operand to get the requested value.  */
4149   int mem_off = 0;
4150   int reg_off = 0;
4151   int const_shift = 0;
4152 
4153   /* We can't use c, n, a, or l.  */
4154   switch (letter)
4155     {
4156     case 'Z':
4157       gcc_assert (CONST_INT_P (op));
4158       /* Print the constant value, less one.  */
4159       fprintf (file, "#%ld", (long) (INTVAL (op) - 1));
4160       return;
4161     case 'Y':
4162       gcc_assert (CONST_INT_P (op));
4163       /* Print the constant value, less four.  */
4164       fprintf (file, "#%ld", (long) (INTVAL (op) - 4));
4165       return;
4166     case 'W':
4167       gcc_assert (CONST_INT_P (op));
4168       /* Print the constant value, less 16.  */
4169       fprintf (file, "#%ld", (long) (INTVAL (op) - 16));
4170       return;
4171     case 'I':
4172       if (GET_CODE (op) == CONST_INT)
4173 	{
4174 	  /* Inverse of constants */
4175 	  int i = INTVAL (op);
4176 	  fprintf (file, "%d", ~i);
4177 	  return;
4178 	}
4179       op = XEXP (op, 0);
4180       break;
4181     case 'r': /* Conditional jump where the condition is reversed.  */
4182       switch (GET_CODE (op))
4183 	{
4184 	case EQ: fprintf (file, "NE"); break;
4185 	case NE: fprintf (file, "EQ"); break;
4186 	case GEU: fprintf (file, "LO"); break;
4187 	case LTU: fprintf (file, "HS"); break;
4188 	case GE: fprintf (file, "L"); break;
4189 	case LT: fprintf (file, "GE"); break;
4190 	  /* Assume these have reversed operands.  */
4191 	case GTU: fprintf (file, "HS"); break;
4192 	case LEU: fprintf (file, "LO"); break;
4193 	case GT: fprintf (file, "GE"); break;
4194 	case LE: fprintf (file, "L"); break;
4195 	default:
4196 	  msp430_print_operand_raw (file, op);
4197 	  break;
4198 	}
4199       return;
4200     case 'R': /* Conditional jump where the operands are reversed.  */
4201       switch (GET_CODE (op))
4202 	{
4203 	case GTU: fprintf (file, "LO"); break;
4204 	case LEU: fprintf (file, "HS"); break;
4205 	case GT: fprintf (file, "L"); break;
4206 	case LE: fprintf (file, "GE"); break;
4207 	default:
4208 	  msp430_print_operand_raw (file, op);
4209 	  break;
4210 	}
4211       return;
4212     case 'p': /* Bit position.  0 == 0x01, 3 = 0x08 etc.  */
4213       gcc_assert (CONST_INT_P (op));
4214       fprintf (file, "#%d", 1 << INTVAL (op));
4215       return;
4216     case 'b':
4217       switch (GET_MODE (op))
4218 	{
4219 	case E_QImode: fprintf (file, ".B"); return;
4220 	case E_HImode: fprintf (file, ".W"); return;
4221 	case E_PSImode: fprintf (file, ".A"); return;
4222 	case E_SImode: fprintf (file, ".A"); return;
4223 	default:
4224 	  return;
4225 	}
4226     case 'd': case 'e': case 'f': case 'g':
4227       if (REG_P (op))
4228 	{
4229 	  output_operand_lossage ("%%d, %%e, %%f, %%g operand modifiers are "
4230 				  "for memory references or constant values "
4231 				  "only");
4232 	  return;
4233 	}
4234       /* fallthru */
4235     case 'B': case 'H': /* high half */
4236     case 'C':
4237     case 'D':
4238       switch (letter)
4239 	{
4240 	case 'd':
4241 	  mem_off = 1;
4242 	  const_shift = 8;
4243 	  break;
4244 	case 'B':
4245 	case 'H':
4246 	  mem_off = 2;
4247 	  reg_off = 1;
4248 	  const_shift = 16;
4249 	  break;
4250 	case 'e':
4251 	  mem_off = 3;
4252 	  const_shift = 24;
4253 	  break;
4254 	case 'C':
4255 	  mem_off = 4;
4256 	  reg_off = 2;
4257 	  const_shift = 32;
4258 	  break;
4259 	case 'f':
4260 	  mem_off = 5;
4261 	  const_shift = 40;
4262 	  break;
4263 	case 'D':
4264 	  mem_off = 6;
4265 	  reg_off = 3;
4266 	  const_shift = 48;
4267 	  break;
4268 	case 'g':
4269 	  mem_off = 7;
4270 	  const_shift = 56;
4271 	  break;
4272 	default:
4273 	  gcc_unreachable ();
4274 	  break;
4275 	}
4276       /* fallthru */
4277     case 'A': case 'L': /* Low half.  */
4278       switch (GET_CODE (op))
4279 	{
4280 	case MEM:
4281 	  /* We don't need to adjust the address for post_inc.  */
4282 	  op = adjust_address (op, Pmode,
4283 			       (GET_CODE (XEXP (op, 0)) == POST_INC)
4284 			       ? 0 : mem_off);
4285 	  break;
4286 	case REG:
4287 	  op = gen_rtx_REG (Pmode, REGNO (op) + reg_off);
4288 	  break;
4289 	case CONST_INT:
4290 	  op = GEN_INT (((long long) INTVAL (op) >> const_shift) & 0xffff);
4291 	  letter = 0;
4292 	  break;
4293 	default:
4294 	  /* If you get here, figure out a test case :-) */
4295 	  gcc_unreachable ();
4296 	}
4297       break;
4298 
4299     case 'X':
4300       /* This is used to turn, for example, an ADD opcode into an ADDX
4301 	 opcode when we're using 20-bit addresses.
4302 	 This can be used for insns which have only one operand which might be
4303 	 a mem.
4304 	 If an insn has two different operands which could be memory operands,
4305 	 then the "Yx" constraint must be used to determine if the X suffix is
4306 	 required by checking both operands.  */
4307       if (GET_MODE (op) == PSImode
4308 	  || !msp430_op_not_in_high_mem (op))
4309 	fprintf (file, "X");
4310       return;
4311 
4312     case 'x':
4313       /* Similarly, but only for PSImodes.  BIC, and other insn patterns using
4314 	 the QHI mode iterator (which includes, QI, HI, and PSImode) use
4315 	 this.  */
4316       if (GET_MODE (op) == PSImode)
4317 	fprintf (file, "X");
4318       return;
4319 
4320     case 'Q':
4321       /* Likewise, for BR -> BRA.  */
4322       if (TARGET_LARGE)
4323 	fprintf (file, "A");
4324       return;
4325 
4326     case 'O':
4327       /* Computes the offset to the top of the stack for the current frame.
4328 	 This has to be done here rather than in, say, msp430_expand_builtin()
4329 	 because builtins are expanded before the frame layout is
4330 	 determined.  */
4331       fprintf (file, "%d",
4332 	       msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
4333 						  STACK_POINTER_REGNUM)
4334 	       - (TARGET_LARGE ? 4 : 2));
4335       return;
4336 
4337     case 'J':
4338       gcc_assert (GET_CODE (op) == CONST_INT);
4339     case 0:
4340       break;
4341     default:
4342       output_operand_lossage ("invalid operand prefix");
4343       return;
4344     }
4345 
4346   switch (GET_CODE (op))
4347     {
4348     case REG:
4349       msp430_print_operand_raw (file, op);
4350       break;
4351 
4352     case MEM:
4353       addr = XEXP (op, 0);
4354       msp430_print_operand_addr (file, GET_MODE (op), addr);
4355       break;
4356 
4357     case CONST:
4358       if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT)
4359 	{
4360 	  op = XEXP (op, 0);
4361 	  switch (INTVAL (XEXP (op, 2)))
4362 	    {
4363 	    case 0:
4364 	      fprintf (file, "#lo (");
4365 	      msp430_print_operand_raw (file, XEXP (op, 0));
4366 	      fprintf (file, ")");
4367 	      break;
4368 
4369 	    case 16:
4370 	      fprintf (file, "#hi (");
4371 	      msp430_print_operand_raw (file, XEXP (op, 0));
4372 	      fprintf (file, ")");
4373 	      break;
4374 
4375 	    default:
4376 	      output_operand_lossage ("invalid zero extract");
4377 	      break;
4378 	    }
4379 	  break;
4380 	}
4381       /* Fall through.  */
4382     case CONST_INT:
4383     case SYMBOL_REF:
4384     case LABEL_REF:
4385       if (letter == 0)
4386 	fprintf (file, "#");
4387       msp430_print_operand_raw (file, op);
4388       break;
4389 
4390     case EQ: fprintf (file, "EQ"); break;
4391     case NE: fprintf (file, "NE"); break;
4392     case GEU: fprintf (file, "HS"); break;
4393     case LTU: fprintf (file, "LO"); break;
4394     case GE: fprintf (file, "GE"); break;
4395     case LT: fprintf (file, "L"); break;
4396 
4397     default:
4398       print_rtl (file, op);
4399       break;
4400     }
4401 }
4402 
4403 
4404 /* Frame stuff.  */
4405 
4406 rtx
msp430_return_addr_rtx(int count)4407 msp430_return_addr_rtx (int count)
4408 {
4409   int ra_size;
4410   if (count)
4411     return NULL_RTX;
4412 
4413   ra_size = TARGET_LARGE ? 4 : 2;
4414   if (crtl->args.pretend_args_size)
4415     ra_size += 2;
4416 
4417   return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx,
4418 					   GEN_INT (- ra_size)));
4419 }
4420 
4421 rtx
msp430_incoming_return_addr_rtx(void)4422 msp430_incoming_return_addr_rtx (void)
4423 {
4424   return gen_rtx_MEM (Pmode, stack_pointer_rtx);
4425 }
4426 
4427 /* If the path to the MSP430-GCC support files has been found by examining
4428    an environment variable (see msp430_check_env_var_for_devices in
4429    msp430-devices.cc), or -mdevices-csv-loc=, register this path as an include
4430    directory so the user can #include msp430.h without needing to specify the
4431    path to the support files with -I.  */
4432 void
msp430_register_pre_includes(const char * sysroot ATTRIBUTE_UNUSED,const char * iprefix ATTRIBUTE_UNUSED,int stdinc ATTRIBUTE_UNUSED)4433 msp430_register_pre_includes (const char *sysroot ATTRIBUTE_UNUSED,
4434 			      const char *iprefix ATTRIBUTE_UNUSED,
4435 			      int stdinc ATTRIBUTE_UNUSED)
4436 {
4437   char *include_dir;
4438   if (msp430_devices_csv_loc)
4439     include_dir = xstrdup (msp430_devices_csv_loc);
4440   else if (msp430_check_env_var_for_devices (&include_dir))
4441     return;
4442   include_dir = msp430_dirname (include_dir);
4443 
4444   include_dir = update_path (include_dir, "");
4445   add_path (include_dir, INC_SYSTEM, false, false);
4446 }
4447 
4448 /* Instruction generation stuff.  */
4449 
4450 /* Generate a sequence of instructions to sign-extend an HI
4451    value into an SI value.  Handles the tricky case where
4452    we are overwriting the destination.
4453    Return the number of bytes used by the emitted instructions.
4454    If RETURN_LENGTH is true then do not emit the assembly instruction
4455    sequence.  */
4456 int
msp430x_extendhisi(rtx * operands,bool return_length)4457 msp430x_extendhisi (rtx * operands, bool return_length)
4458 {
4459   if (REGNO (operands[0]) == REGNO (operands[1]))
4460     {
4461       /* Low word of dest == source word.  */
4462       if (!return_length)
4463 	output_asm_insn ("BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
4464 			 operands);
4465       return 8;
4466     }
4467   else if (! msp430x)
4468     {
4469       /* Note: This sequence is approximately the same length as invoking a
4470 	 helper function to perform the sign-extension, as in:
4471 
4472 	 MOV.W  %1, %L0
4473 	 MOV.W  %1, r12
4474 	 CALL   __mspabi_srai_15
4475 	 MOV.W  r12, %H0
4476 
4477 	 but this version does not involve any function calls or using argument
4478 	 registers, so it reduces register pressure.  */
4479       if (!return_length)
4480 	output_asm_insn ("MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0",
4481 			 operands);
4482       return 10;
4483     }
4484   else if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
4485     {
4486       /* High word of dest == source word.  */
4487       if (!return_length)
4488 	output_asm_insn ("MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0",
4489 			 operands);
4490       return 6;
4491     }
4492 
4493   /* No overlap between dest and source.  */
4494   if (!return_length)
4495     output_asm_insn ("MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0",
4496 		     operands);
4497   return 8;
4498 }
4499 
4500 /* Stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)).  */
4501 
4502 #undef TARGET_CAN_CHANGE_MODE_CLASS
4503 #define TARGET_CAN_CHANGE_MODE_CLASS msp430_can_change_mode_class
4504 
4505 static bool
msp430_can_change_mode_class(machine_mode from,machine_mode to,reg_class_t)4506 msp430_can_change_mode_class (machine_mode from, machine_mode to, reg_class_t)
4507 {
4508   if ((to == PSImode && from == SImode)
4509       || (to == SImode && from == PSImode)
4510       || (to == DImode && from == PSImode)
4511       || (to == PSImode && from == DImode))
4512     return false;
4513   return true;
4514 }
4515 
4516 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
4517 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
4518 
4519 struct gcc_target targetm = TARGET_INITIALIZER;
4520 
4521 #include "gt-msp430.h"
4522