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