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