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