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