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