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