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