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