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