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