Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/v850/v850.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Subroutines for insn-output.c for NEC V850 series | |
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | |
3 2006, 2007, 2008 Free Software Foundation, Inc. | |
4 Contributed by Jeff Law (law@cygnus.com). | |
5 | |
6 This file is part of GCC. | |
7 | |
8 GCC is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by | |
10 the Free Software Foundation; either version 3, or (at your option) | |
11 any later version. | |
12 | |
13 GCC is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 #include "config.h" | |
23 #include "system.h" | |
24 #include "coretypes.h" | |
25 #include "tm.h" | |
26 #include "tree.h" | |
27 #include "rtl.h" | |
28 #include "regs.h" | |
29 #include "hard-reg-set.h" | |
30 #include "real.h" | |
31 #include "insn-config.h" | |
32 #include "conditions.h" | |
33 #include "output.h" | |
34 #include "insn-attr.h" | |
35 #include "flags.h" | |
36 #include "recog.h" | |
37 #include "expr.h" | |
38 #include "function.h" | |
39 #include "toplev.h" | |
40 #include "ggc.h" | |
41 #include "integrate.h" | |
42 #include "tm_p.h" | |
43 #include "target.h" | |
44 #include "target-def.h" | |
45 #include "df.h" | |
46 | |
47 #ifndef streq | |
48 #define streq(a,b) (strcmp (a, b) == 0) | |
49 #endif | |
50 | |
51 /* Function prototypes for stupid compilers: */ | |
52 static bool v850_handle_option (size_t, const char *, int); | |
53 static void const_double_split (rtx, HOST_WIDE_INT *, HOST_WIDE_INT *); | |
54 static int const_costs_int (HOST_WIDE_INT, int); | |
55 static int const_costs (rtx, enum rtx_code); | |
56 static bool v850_rtx_costs (rtx, int, int, int *, bool); | |
57 static void substitute_ep_register (rtx, rtx, int, int, rtx *, rtx *); | |
58 static void v850_reorg (void); | |
59 static int ep_memory_offset (enum machine_mode, int); | |
60 static void v850_set_data_area (tree, v850_data_area); | |
61 const struct attribute_spec v850_attribute_table[]; | |
62 static tree v850_handle_interrupt_attribute (tree *, tree, tree, int, bool *); | |
63 static tree v850_handle_data_area_attribute (tree *, tree, tree, int, bool *); | |
64 static void v850_insert_attributes (tree, tree *); | |
65 static void v850_asm_init_sections (void); | |
66 static section *v850_select_section (tree, int, unsigned HOST_WIDE_INT); | |
67 static void v850_encode_data_area (tree, rtx); | |
68 static void v850_encode_section_info (tree, rtx, int); | |
69 static bool v850_return_in_memory (const_tree, const_tree); | |
70 static void v850_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, | |
71 tree, int *, int); | |
72 static bool v850_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, | |
73 const_tree, bool); | |
74 static int v850_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, | |
75 tree, bool); | |
76 | |
77 /* Information about the various small memory areas. */ | |
78 struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] = | |
79 { | |
80 /* name max physical max */ | |
81 { "tda", 0, 256 }, | |
82 { "sda", 0, 65536 }, | |
83 { "zda", 0, 32768 }, | |
84 }; | |
85 | |
86 /* Names of the various data areas used on the v850. */ | |
87 tree GHS_default_section_names [(int) COUNT_OF_GHS_SECTION_KINDS]; | |
88 tree GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_KINDS]; | |
89 | |
90 /* Track the current data area set by the data area pragma (which | |
91 can be nested). Tested by check_default_data_area. */ | |
92 data_area_stack_element * data_area_stack = NULL; | |
93 | |
94 /* True if we don't need to check any more if the current | |
95 function is an interrupt handler. */ | |
96 static int v850_interrupt_cache_p = FALSE; | |
97 | |
98 /* Whether current function is an interrupt handler. */ | |
99 static int v850_interrupt_p = FALSE; | |
100 | |
101 static GTY(()) section *rosdata_section; | |
102 static GTY(()) section *rozdata_section; | |
103 static GTY(()) section *tdata_section; | |
104 static GTY(()) section *zdata_section; | |
105 static GTY(()) section *zbss_section; | |
106 | |
107 /* Initialize the GCC target structure. */ | |
108 #undef TARGET_ASM_ALIGNED_HI_OP | |
109 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t" | |
110 | |
111 #undef TARGET_ATTRIBUTE_TABLE | |
112 #define TARGET_ATTRIBUTE_TABLE v850_attribute_table | |
113 | |
114 #undef TARGET_INSERT_ATTRIBUTES | |
115 #define TARGET_INSERT_ATTRIBUTES v850_insert_attributes | |
116 | |
117 #undef TARGET_ASM_SELECT_SECTION | |
118 #define TARGET_ASM_SELECT_SECTION v850_select_section | |
119 | |
120 /* The assembler supports switchable .bss sections, but | |
121 v850_select_section doesn't yet make use of them. */ | |
122 #undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS | |
123 #define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS false | |
124 | |
125 #undef TARGET_ENCODE_SECTION_INFO | |
126 #define TARGET_ENCODE_SECTION_INFO v850_encode_section_info | |
127 | |
128 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE | |
129 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true | |
130 | |
131 #undef TARGET_DEFAULT_TARGET_FLAGS | |
132 #define TARGET_DEFAULT_TARGET_FLAGS (MASK_DEFAULT | MASK_APP_REGS) | |
133 #undef TARGET_HANDLE_OPTION | |
134 #define TARGET_HANDLE_OPTION v850_handle_option | |
135 | |
136 #undef TARGET_RTX_COSTS | |
137 #define TARGET_RTX_COSTS v850_rtx_costs | |
138 | |
139 #undef TARGET_ADDRESS_COST | |
140 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0 | |
141 | |
142 #undef TARGET_MACHINE_DEPENDENT_REORG | |
143 #define TARGET_MACHINE_DEPENDENT_REORG v850_reorg | |
144 | |
145 #undef TARGET_PROMOTE_PROTOTYPES | |
146 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true | |
147 | |
148 #undef TARGET_RETURN_IN_MEMORY | |
149 #define TARGET_RETURN_IN_MEMORY v850_return_in_memory | |
150 | |
151 #undef TARGET_PASS_BY_REFERENCE | |
152 #define TARGET_PASS_BY_REFERENCE v850_pass_by_reference | |
153 | |
154 #undef TARGET_CALLEE_COPIES | |
155 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true | |
156 | |
157 #undef TARGET_SETUP_INCOMING_VARARGS | |
158 #define TARGET_SETUP_INCOMING_VARARGS v850_setup_incoming_varargs | |
159 | |
160 #undef TARGET_ARG_PARTIAL_BYTES | |
161 #define TARGET_ARG_PARTIAL_BYTES v850_arg_partial_bytes | |
162 | |
163 struct gcc_target targetm = TARGET_INITIALIZER; | |
164 | |
165 /* Set the maximum size of small memory area TYPE to the value given | |
166 by VALUE. Return true if VALUE was syntactically correct. VALUE | |
167 starts with the argument separator: either "-" or "=". */ | |
168 | |
169 static bool | |
170 v850_handle_memory_option (enum small_memory_type type, const char *value) | |
171 { | |
172 int i, size; | |
173 | |
174 if (*value != '-' && *value != '=') | |
175 return false; | |
176 | |
177 value++; | |
178 for (i = 0; value[i]; i++) | |
179 if (!ISDIGIT (value[i])) | |
180 return false; | |
181 | |
182 size = atoi (value); | |
183 if (size > small_memory[type].physical_max) | |
184 error ("value passed to %<-m%s%> is too large", small_memory[type].name); | |
185 else | |
186 small_memory[type].max = size; | |
187 return true; | |
188 } | |
189 | |
190 /* Implement TARGET_HANDLE_OPTION. */ | |
191 | |
192 static bool | |
193 v850_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED) | |
194 { | |
195 switch (code) | |
196 { | |
197 case OPT_mspace: | |
198 target_flags |= MASK_EP | MASK_PROLOG_FUNCTION; | |
199 return true; | |
200 | |
201 case OPT_mv850: | |
202 target_flags &= ~(MASK_CPU ^ MASK_V850); | |
203 return true; | |
204 | |
205 case OPT_mv850e: | |
206 case OPT_mv850e1: | |
207 target_flags &= ~(MASK_CPU ^ MASK_V850E); | |
208 return true; | |
209 | |
210 case OPT_mtda: | |
211 return v850_handle_memory_option (SMALL_MEMORY_TDA, arg); | |
212 | |
213 case OPT_msda: | |
214 return v850_handle_memory_option (SMALL_MEMORY_SDA, arg); | |
215 | |
216 case OPT_mzda: | |
217 return v850_handle_memory_option (SMALL_MEMORY_ZDA, arg); | |
218 | |
219 default: | |
220 return true; | |
221 } | |
222 } | |
223 | |
224 static bool | |
225 v850_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, | |
226 enum machine_mode mode, const_tree type, | |
227 bool named ATTRIBUTE_UNUSED) | |
228 { | |
229 unsigned HOST_WIDE_INT size; | |
230 | |
231 if (type) | |
232 size = int_size_in_bytes (type); | |
233 else | |
234 size = GET_MODE_SIZE (mode); | |
235 | |
236 return size > 8; | |
237 } | |
238 | |
239 /* Return an RTX to represent where a value with mode MODE will be returned | |
240 from a function. If the result is 0, the argument is pushed. */ | |
241 | |
242 rtx | |
243 function_arg (CUMULATIVE_ARGS * cum, | |
244 enum machine_mode mode, | |
245 tree type, | |
246 int named) | |
247 { | |
248 rtx result = 0; | |
249 int size, align; | |
250 | |
251 if (TARGET_GHS && !named) | |
252 return NULL_RTX; | |
253 | |
254 if (mode == BLKmode) | |
255 size = int_size_in_bytes (type); | |
256 else | |
257 size = GET_MODE_SIZE (mode); | |
258 | |
259 if (size < 1) | |
260 return 0; | |
261 | |
262 if (type) | |
263 align = TYPE_ALIGN (type) / BITS_PER_UNIT; | |
264 else | |
265 align = size; | |
266 | |
267 cum->nbytes = (cum->nbytes + align - 1) &~(align - 1); | |
268 | |
269 if (cum->nbytes > 4 * UNITS_PER_WORD) | |
270 return 0; | |
271 | |
272 if (type == NULL_TREE | |
273 && cum->nbytes + size > 4 * UNITS_PER_WORD) | |
274 return 0; | |
275 | |
276 switch (cum->nbytes / UNITS_PER_WORD) | |
277 { | |
278 case 0: | |
279 result = gen_rtx_REG (mode, 6); | |
280 break; | |
281 case 1: | |
282 result = gen_rtx_REG (mode, 7); | |
283 break; | |
284 case 2: | |
285 result = gen_rtx_REG (mode, 8); | |
286 break; | |
287 case 3: | |
288 result = gen_rtx_REG (mode, 9); | |
289 break; | |
290 default: | |
291 result = 0; | |
292 } | |
293 | |
294 return result; | |
295 } | |
296 | |
297 | |
298 /* Return the number of bytes which must be put into registers | |
299 for values which are part in registers and part in memory. */ | |
300 | |
301 static int | |
302 v850_arg_partial_bytes (CUMULATIVE_ARGS * cum, enum machine_mode mode, | |
303 tree type, bool named) | |
304 { | |
305 int size, align; | |
306 | |
307 if (TARGET_GHS && !named) | |
308 return 0; | |
309 | |
310 if (mode == BLKmode) | |
311 size = int_size_in_bytes (type); | |
312 else | |
313 size = GET_MODE_SIZE (mode); | |
314 | |
315 if (type) | |
316 align = TYPE_ALIGN (type) / BITS_PER_UNIT; | |
317 else | |
318 align = size; | |
319 | |
320 cum->nbytes = (cum->nbytes + align - 1) &~(align - 1); | |
321 | |
322 if (cum->nbytes > 4 * UNITS_PER_WORD) | |
323 return 0; | |
324 | |
325 if (cum->nbytes + size <= 4 * UNITS_PER_WORD) | |
326 return 0; | |
327 | |
328 if (type == NULL_TREE | |
329 && cum->nbytes + size > 4 * UNITS_PER_WORD) | |
330 return 0; | |
331 | |
332 return 4 * UNITS_PER_WORD - cum->nbytes; | |
333 } | |
334 | |
335 | |
336 /* Return the high and low words of a CONST_DOUBLE */ | |
337 | |
338 static void | |
339 const_double_split (rtx x, HOST_WIDE_INT * p_high, HOST_WIDE_INT * p_low) | |
340 { | |
341 if (GET_CODE (x) == CONST_DOUBLE) | |
342 { | |
343 long t[2]; | |
344 REAL_VALUE_TYPE rv; | |
345 | |
346 switch (GET_MODE (x)) | |
347 { | |
348 case DFmode: | |
349 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
350 REAL_VALUE_TO_TARGET_DOUBLE (rv, t); | |
351 *p_high = t[1]; /* since v850 is little endian */ | |
352 *p_low = t[0]; /* high is second word */ | |
353 return; | |
354 | |
355 case SFmode: | |
356 REAL_VALUE_FROM_CONST_DOUBLE (rv, x); | |
357 REAL_VALUE_TO_TARGET_SINGLE (rv, *p_high); | |
358 *p_low = 0; | |
359 return; | |
360 | |
361 case VOIDmode: | |
362 case DImode: | |
363 *p_high = CONST_DOUBLE_HIGH (x); | |
364 *p_low = CONST_DOUBLE_LOW (x); | |
365 return; | |
366 | |
367 default: | |
368 break; | |
369 } | |
370 } | |
371 | |
372 fatal_insn ("const_double_split got a bad insn:", x); | |
373 } | |
374 | |
375 | |
376 /* Return the cost of the rtx R with code CODE. */ | |
377 | |
378 static int | |
379 const_costs_int (HOST_WIDE_INT value, int zero_cost) | |
380 { | |
381 if (CONST_OK_FOR_I (value)) | |
382 return zero_cost; | |
383 else if (CONST_OK_FOR_J (value)) | |
384 return 1; | |
385 else if (CONST_OK_FOR_K (value)) | |
386 return 2; | |
387 else | |
388 return 4; | |
389 } | |
390 | |
391 static int | |
392 const_costs (rtx r, enum rtx_code c) | |
393 { | |
394 HOST_WIDE_INT high, low; | |
395 | |
396 switch (c) | |
397 { | |
398 case CONST_INT: | |
399 return const_costs_int (INTVAL (r), 0); | |
400 | |
401 case CONST_DOUBLE: | |
402 const_double_split (r, &high, &low); | |
403 if (GET_MODE (r) == SFmode) | |
404 return const_costs_int (high, 1); | |
405 else | |
406 return const_costs_int (high, 1) + const_costs_int (low, 1); | |
407 | |
408 case SYMBOL_REF: | |
409 case LABEL_REF: | |
410 case CONST: | |
411 return 2; | |
412 | |
413 case HIGH: | |
414 return 1; | |
415 | |
416 default: | |
417 return 4; | |
418 } | |
419 } | |
420 | |
421 static bool | |
422 v850_rtx_costs (rtx x, | |
423 int code, | |
424 int outer_code ATTRIBUTE_UNUSED, | |
425 int * total, bool speed) | |
426 { | |
427 switch (code) | |
428 { | |
429 case CONST_INT: | |
430 case CONST_DOUBLE: | |
431 case CONST: | |
432 case SYMBOL_REF: | |
433 case LABEL_REF: | |
434 *total = COSTS_N_INSNS (const_costs (x, code)); | |
435 return true; | |
436 | |
437 case MOD: | |
438 case DIV: | |
439 case UMOD: | |
440 case UDIV: | |
441 if (TARGET_V850E && !speed) | |
442 *total = 6; | |
443 else | |
444 *total = 60; | |
445 return true; | |
446 | |
447 case MULT: | |
448 if (TARGET_V850E | |
449 && ( GET_MODE (x) == SImode | |
450 || GET_MODE (x) == HImode | |
451 || GET_MODE (x) == QImode)) | |
452 { | |
453 if (GET_CODE (XEXP (x, 1)) == REG) | |
454 *total = 4; | |
455 else if (GET_CODE (XEXP (x, 1)) == CONST_INT) | |
456 { | |
457 if (CONST_OK_FOR_O (INTVAL (XEXP (x, 1)))) | |
458 *total = 6; | |
459 else if (CONST_OK_FOR_K (INTVAL (XEXP (x, 1)))) | |
460 *total = 10; | |
461 } | |
462 } | |
463 else | |
464 *total = 20; | |
465 return true; | |
466 | |
467 default: | |
468 return false; | |
469 } | |
470 } | |
471 | |
472 /* Print operand X using operand code CODE to assembly language output file | |
473 FILE. */ | |
474 | |
475 void | |
476 print_operand (FILE * file, rtx x, int code) | |
477 { | |
478 HOST_WIDE_INT high, low; | |
479 | |
480 switch (code) | |
481 { | |
482 case 'c': | |
483 /* We use 'c' operands with symbols for .vtinherit */ | |
484 if (GET_CODE (x) == SYMBOL_REF) | |
485 { | |
486 output_addr_const(file, x); | |
487 break; | |
488 } | |
489 /* fall through */ | |
490 case 'b': | |
491 case 'B': | |
492 case 'C': | |
493 switch ((code == 'B' || code == 'C') | |
494 ? reverse_condition (GET_CODE (x)) : GET_CODE (x)) | |
495 { | |
496 case NE: | |
497 if (code == 'c' || code == 'C') | |
498 fprintf (file, "nz"); | |
499 else | |
500 fprintf (file, "ne"); | |
501 break; | |
502 case EQ: | |
503 if (code == 'c' || code == 'C') | |
504 fprintf (file, "z"); | |
505 else | |
506 fprintf (file, "e"); | |
507 break; | |
508 case GE: | |
509 fprintf (file, "ge"); | |
510 break; | |
511 case GT: | |
512 fprintf (file, "gt"); | |
513 break; | |
514 case LE: | |
515 fprintf (file, "le"); | |
516 break; | |
517 case LT: | |
518 fprintf (file, "lt"); | |
519 break; | |
520 case GEU: | |
521 fprintf (file, "nl"); | |
522 break; | |
523 case GTU: | |
524 fprintf (file, "h"); | |
525 break; | |
526 case LEU: | |
527 fprintf (file, "nh"); | |
528 break; | |
529 case LTU: | |
530 fprintf (file, "l"); | |
531 break; | |
532 default: | |
533 gcc_unreachable (); | |
534 } | |
535 break; | |
536 case 'F': /* high word of CONST_DOUBLE */ | |
537 switch (GET_CODE (x)) | |
538 { | |
539 case CONST_INT: | |
540 fprintf (file, "%d", (INTVAL (x) >= 0) ? 0 : -1); | |
541 break; | |
542 | |
543 case CONST_DOUBLE: | |
544 const_double_split (x, &high, &low); | |
545 fprintf (file, "%ld", (long) high); | |
546 break; | |
547 | |
548 default: | |
549 gcc_unreachable (); | |
550 } | |
551 break; | |
552 case 'G': /* low word of CONST_DOUBLE */ | |
553 switch (GET_CODE (x)) | |
554 { | |
555 case CONST_INT: | |
556 fprintf (file, "%ld", (long) INTVAL (x)); | |
557 break; | |
558 | |
559 case CONST_DOUBLE: | |
560 const_double_split (x, &high, &low); | |
561 fprintf (file, "%ld", (long) low); | |
562 break; | |
563 | |
564 default: | |
565 gcc_unreachable (); | |
566 } | |
567 break; | |
568 case 'L': | |
569 fprintf (file, "%d\n", (int)(INTVAL (x) & 0xffff)); | |
570 break; | |
571 case 'M': | |
572 fprintf (file, "%d", exact_log2 (INTVAL (x))); | |
573 break; | |
574 case 'O': | |
575 gcc_assert (special_symbolref_operand (x, VOIDmode)); | |
576 | |
577 if (GET_CODE (x) == CONST) | |
578 x = XEXP (XEXP (x, 0), 0); | |
579 else | |
580 gcc_assert (GET_CODE (x) == SYMBOL_REF); | |
581 | |
582 if (SYMBOL_REF_ZDA_P (x)) | |
583 fprintf (file, "zdaoff"); | |
584 else if (SYMBOL_REF_SDA_P (x)) | |
585 fprintf (file, "sdaoff"); | |
586 else if (SYMBOL_REF_TDA_P (x)) | |
587 fprintf (file, "tdaoff"); | |
588 else | |
589 gcc_unreachable (); | |
590 break; | |
591 case 'P': | |
592 gcc_assert (special_symbolref_operand (x, VOIDmode)); | |
593 output_addr_const (file, x); | |
594 break; | |
595 case 'Q': | |
596 gcc_assert (special_symbolref_operand (x, VOIDmode)); | |
597 | |
598 if (GET_CODE (x) == CONST) | |
599 x = XEXP (XEXP (x, 0), 0); | |
600 else | |
601 gcc_assert (GET_CODE (x) == SYMBOL_REF); | |
602 | |
603 if (SYMBOL_REF_ZDA_P (x)) | |
604 fprintf (file, "r0"); | |
605 else if (SYMBOL_REF_SDA_P (x)) | |
606 fprintf (file, "gp"); | |
607 else if (SYMBOL_REF_TDA_P (x)) | |
608 fprintf (file, "ep"); | |
609 else | |
610 gcc_unreachable (); | |
611 break; | |
612 case 'R': /* 2nd word of a double. */ | |
613 switch (GET_CODE (x)) | |
614 { | |
615 case REG: | |
616 fprintf (file, reg_names[REGNO (x) + 1]); | |
617 break; | |
618 case MEM: | |
619 x = XEXP (adjust_address (x, SImode, 4), 0); | |
620 print_operand_address (file, x); | |
621 if (GET_CODE (x) == CONST_INT) | |
622 fprintf (file, "[r0]"); | |
623 break; | |
624 | |
625 default: | |
626 break; | |
627 } | |
628 break; | |
629 case 'S': | |
630 { | |
631 /* If it's a reference to a TDA variable, use sst/sld vs. st/ld. */ | |
632 if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), FALSE)) | |
633 fputs ("s", file); | |
634 | |
635 break; | |
636 } | |
637 case 'T': | |
638 { | |
639 /* Like an 'S' operand above, but for unsigned loads only. */ | |
640 if (GET_CODE (x) == MEM && ep_memory_operand (x, GET_MODE (x), TRUE)) | |
641 fputs ("s", file); | |
642 | |
643 break; | |
644 } | |
645 case 'W': /* print the instruction suffix */ | |
646 switch (GET_MODE (x)) | |
647 { | |
648 default: | |
649 gcc_unreachable (); | |
650 | |
651 case QImode: fputs (".b", file); break; | |
652 case HImode: fputs (".h", file); break; | |
653 case SImode: fputs (".w", file); break; | |
654 case SFmode: fputs (".w", file); break; | |
655 } | |
656 break; | |
657 case '.': /* register r0 */ | |
658 fputs (reg_names[0], file); | |
659 break; | |
660 case 'z': /* reg or zero */ | |
661 if (GET_CODE (x) == REG) | |
662 fputs (reg_names[REGNO (x)], file); | |
663 else | |
664 { | |
665 gcc_assert (x == const0_rtx); | |
666 fputs (reg_names[0], file); | |
667 } | |
668 break; | |
669 default: | |
670 switch (GET_CODE (x)) | |
671 { | |
672 case MEM: | |
673 if (GET_CODE (XEXP (x, 0)) == CONST_INT) | |
674 output_address (gen_rtx_PLUS (SImode, gen_rtx_REG (SImode, 0), | |
675 XEXP (x, 0))); | |
676 else | |
677 output_address (XEXP (x, 0)); | |
678 break; | |
679 | |
680 case REG: | |
681 fputs (reg_names[REGNO (x)], file); | |
682 break; | |
683 case SUBREG: | |
684 fputs (reg_names[subreg_regno (x)], file); | |
685 break; | |
686 case CONST_INT: | |
687 case SYMBOL_REF: | |
688 case CONST: | |
689 case LABEL_REF: | |
690 case CODE_LABEL: | |
691 print_operand_address (file, x); | |
692 break; | |
693 default: | |
694 gcc_unreachable (); | |
695 } | |
696 break; | |
697 | |
698 } | |
699 } | |
700 | |
701 | |
702 /* Output assembly language output for the address ADDR to FILE. */ | |
703 | |
704 void | |
705 print_operand_address (FILE * file, rtx addr) | |
706 { | |
707 switch (GET_CODE (addr)) | |
708 { | |
709 case REG: | |
710 fprintf (file, "0["); | |
711 print_operand (file, addr, 0); | |
712 fprintf (file, "]"); | |
713 break; | |
714 case LO_SUM: | |
715 if (GET_CODE (XEXP (addr, 0)) == REG) | |
716 { | |
717 /* reg,foo */ | |
718 fprintf (file, "lo("); | |
719 print_operand (file, XEXP (addr, 1), 0); | |
720 fprintf (file, ")["); | |
721 print_operand (file, XEXP (addr, 0), 0); | |
722 fprintf (file, "]"); | |
723 } | |
724 break; | |
725 case PLUS: | |
726 if (GET_CODE (XEXP (addr, 0)) == REG | |
727 || GET_CODE (XEXP (addr, 0)) == SUBREG) | |
728 { | |
729 /* reg,foo */ | |
730 print_operand (file, XEXP (addr, 1), 0); | |
731 fprintf (file, "["); | |
732 print_operand (file, XEXP (addr, 0), 0); | |
733 fprintf (file, "]"); | |
734 } | |
735 else | |
736 { | |
737 print_operand (file, XEXP (addr, 0), 0); | |
738 fprintf (file, "+"); | |
739 print_operand (file, XEXP (addr, 1), 0); | |
740 } | |
741 break; | |
742 case SYMBOL_REF: | |
743 { | |
744 const char *off_name = NULL; | |
745 const char *reg_name = NULL; | |
746 | |
747 if (SYMBOL_REF_ZDA_P (addr)) | |
748 { | |
749 off_name = "zdaoff"; | |
750 reg_name = "r0"; | |
751 } | |
752 else if (SYMBOL_REF_SDA_P (addr)) | |
753 { | |
754 off_name = "sdaoff"; | |
755 reg_name = "gp"; | |
756 } | |
757 else if (SYMBOL_REF_TDA_P (addr)) | |
758 { | |
759 off_name = "tdaoff"; | |
760 reg_name = "ep"; | |
761 } | |
762 | |
763 if (off_name) | |
764 fprintf (file, "%s(", off_name); | |
765 output_addr_const (file, addr); | |
766 if (reg_name) | |
767 fprintf (file, ")[%s]", reg_name); | |
768 } | |
769 break; | |
770 case CONST: | |
771 if (special_symbolref_operand (addr, VOIDmode)) | |
772 { | |
773 rtx x = XEXP (XEXP (addr, 0), 0); | |
774 const char *off_name; | |
775 const char *reg_name; | |
776 | |
777 if (SYMBOL_REF_ZDA_P (x)) | |
778 { | |
779 off_name = "zdaoff"; | |
780 reg_name = "r0"; | |
781 } | |
782 else if (SYMBOL_REF_SDA_P (x)) | |
783 { | |
784 off_name = "sdaoff"; | |
785 reg_name = "gp"; | |
786 } | |
787 else if (SYMBOL_REF_TDA_P (x)) | |
788 { | |
789 off_name = "tdaoff"; | |
790 reg_name = "ep"; | |
791 } | |
792 else | |
793 gcc_unreachable (); | |
794 | |
795 fprintf (file, "%s(", off_name); | |
796 output_addr_const (file, addr); | |
797 fprintf (file, ")[%s]", reg_name); | |
798 } | |
799 else | |
800 output_addr_const (file, addr); | |
801 break; | |
802 default: | |
803 output_addr_const (file, addr); | |
804 break; | |
805 } | |
806 } | |
807 | |
808 /* When assemble_integer is used to emit the offsets for a switch | |
809 table it can encounter (TRUNCATE:HI (MINUS:SI (LABEL_REF:SI) (LABEL_REF:SI))). | |
810 output_addr_const will normally barf at this, but it is OK to omit | |
811 the truncate and just emit the difference of the two labels. The | |
812 .hword directive will automatically handle the truncation for us. | |
813 | |
814 Returns 1 if rtx was handled, 0 otherwise. */ | |
815 | |
816 int | |
817 v850_output_addr_const_extra (FILE * file, rtx x) | |
818 { | |
819 if (GET_CODE (x) != TRUNCATE) | |
820 return 0; | |
821 | |
822 x = XEXP (x, 0); | |
823 | |
824 /* We must also handle the case where the switch table was passed a | |
825 constant value and so has been collapsed. In this case the first | |
826 label will have been deleted. In such a case it is OK to emit | |
827 nothing, since the table will not be used. | |
828 (cf gcc.c-torture/compile/990801-1.c). */ | |
829 if (GET_CODE (x) == MINUS | |
830 && GET_CODE (XEXP (x, 0)) == LABEL_REF | |
831 && GET_CODE (XEXP (XEXP (x, 0), 0)) == CODE_LABEL | |
832 && INSN_DELETED_P (XEXP (XEXP (x, 0), 0))) | |
833 return 1; | |
834 | |
835 output_addr_const (file, x); | |
836 return 1; | |
837 } | |
838 | |
839 /* Return appropriate code to load up a 1, 2, or 4 integer/floating | |
840 point value. */ | |
841 | |
842 const char * | |
843 output_move_single (rtx * operands) | |
844 { | |
845 rtx dst = operands[0]; | |
846 rtx src = operands[1]; | |
847 | |
848 if (REG_P (dst)) | |
849 { | |
850 if (REG_P (src)) | |
851 return "mov %1,%0"; | |
852 | |
853 else if (GET_CODE (src) == CONST_INT) | |
854 { | |
855 HOST_WIDE_INT value = INTVAL (src); | |
856 | |
857 if (CONST_OK_FOR_J (value)) /* Signed 5-bit immediate. */ | |
858 return "mov %1,%0"; | |
859 | |
860 else if (CONST_OK_FOR_K (value)) /* Signed 16-bit immediate. */ | |
861 return "movea lo(%1),%.,%0"; | |
862 | |
863 else if (CONST_OK_FOR_L (value)) /* Upper 16 bits were set. */ | |
864 return "movhi hi(%1),%.,%0"; | |
865 | |
866 /* A random constant. */ | |
867 else if (TARGET_V850E) | |
868 return "mov %1,%0"; | |
869 else | |
870 return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0"; | |
871 } | |
872 | |
873 else if (GET_CODE (src) == CONST_DOUBLE && GET_MODE (src) == SFmode) | |
874 { | |
875 HOST_WIDE_INT high, low; | |
876 | |
877 const_double_split (src, &high, &low); | |
878 | |
879 if (CONST_OK_FOR_J (high)) /* Signed 5-bit immediate. */ | |
880 return "mov %F1,%0"; | |
881 | |
882 else if (CONST_OK_FOR_K (high)) /* Signed 16-bit immediate. */ | |
883 return "movea lo(%F1),%.,%0"; | |
884 | |
885 else if (CONST_OK_FOR_L (high)) /* Upper 16 bits were set. */ | |
886 return "movhi hi(%F1),%.,%0"; | |
887 | |
888 /* A random constant. */ | |
889 else if (TARGET_V850E) | |
890 return "mov %F1,%0"; | |
891 | |
892 else | |
893 return "movhi hi(%F1),%.,%0\n\tmovea lo(%F1),%0,%0"; | |
894 } | |
895 | |
896 else if (GET_CODE (src) == MEM) | |
897 return "%S1ld%W1 %1,%0"; | |
898 | |
899 else if (special_symbolref_operand (src, VOIDmode)) | |
900 return "movea %O1(%P1),%Q1,%0"; | |
901 | |
902 else if (GET_CODE (src) == LABEL_REF | |
903 || GET_CODE (src) == SYMBOL_REF | |
904 || GET_CODE (src) == CONST) | |
905 { | |
906 if (TARGET_V850E) | |
907 return "mov hilo(%1),%0"; | |
908 else | |
909 return "movhi hi(%1),%.,%0\n\tmovea lo(%1),%0,%0"; | |
910 } | |
911 | |
912 else if (GET_CODE (src) == HIGH) | |
913 return "movhi hi(%1),%.,%0"; | |
914 | |
915 else if (GET_CODE (src) == LO_SUM) | |
916 { | |
917 operands[2] = XEXP (src, 0); | |
918 operands[3] = XEXP (src, 1); | |
919 return "movea lo(%3),%2,%0"; | |
920 } | |
921 } | |
922 | |
923 else if (GET_CODE (dst) == MEM) | |
924 { | |
925 if (REG_P (src)) | |
926 return "%S0st%W0 %1,%0"; | |
927 | |
928 else if (GET_CODE (src) == CONST_INT && INTVAL (src) == 0) | |
929 return "%S0st%W0 %.,%0"; | |
930 | |
931 else if (GET_CODE (src) == CONST_DOUBLE | |
932 && CONST0_RTX (GET_MODE (dst)) == src) | |
933 return "%S0st%W0 %.,%0"; | |
934 } | |
935 | |
936 fatal_insn ("output_move_single:", gen_rtx_SET (VOIDmode, dst, src)); | |
937 return ""; | |
938 } | |
939 | |
940 | |
941 /* Return maximum offset supported for a short EP memory reference of mode | |
942 MODE and signedness UNSIGNEDP. */ | |
943 | |
944 static int | |
945 ep_memory_offset (enum machine_mode mode, int unsignedp ATTRIBUTE_UNUSED) | |
946 { | |
947 int max_offset = 0; | |
948 | |
949 switch (mode) | |
950 { | |
951 case QImode: | |
952 if (TARGET_SMALL_SLD) | |
953 max_offset = (1 << 4); | |
954 else if (TARGET_V850E | |
955 && ( ( unsignedp && ! TARGET_US_BIT_SET) | |
956 || (! unsignedp && TARGET_US_BIT_SET))) | |
957 max_offset = (1 << 4); | |
958 else | |
959 max_offset = (1 << 7); | |
960 break; | |
961 | |
962 case HImode: | |
963 if (TARGET_SMALL_SLD) | |
964 max_offset = (1 << 5); | |
965 else if (TARGET_V850E | |
966 && ( ( unsignedp && ! TARGET_US_BIT_SET) | |
967 || (! unsignedp && TARGET_US_BIT_SET))) | |
968 max_offset = (1 << 5); | |
969 else | |
970 max_offset = (1 << 8); | |
971 break; | |
972 | |
973 case SImode: | |
974 case SFmode: | |
975 max_offset = (1 << 8); | |
976 break; | |
977 | |
978 default: | |
979 break; | |
980 } | |
981 | |
982 return max_offset; | |
983 } | |
984 | |
985 /* Return true if OP is a valid short EP memory reference */ | |
986 | |
987 int | |
988 ep_memory_operand (rtx op, enum machine_mode mode, int unsigned_load) | |
989 { | |
990 rtx addr, op0, op1; | |
991 int max_offset; | |
992 int mask; | |
993 | |
994 /* If we are not using the EP register on a per-function basis | |
995 then do not allow this optimization at all. This is to | |
996 prevent the use of the SLD/SST instructions which cannot be | |
997 guaranteed to work properly due to a hardware bug. */ | |
998 if (!TARGET_EP) | |
999 return FALSE; | |
1000 | |
1001 if (GET_CODE (op) != MEM) | |
1002 return FALSE; | |
1003 | |
1004 max_offset = ep_memory_offset (mode, unsigned_load); | |
1005 | |
1006 mask = GET_MODE_SIZE (mode) - 1; | |
1007 | |
1008 addr = XEXP (op, 0); | |
1009 if (GET_CODE (addr) == CONST) | |
1010 addr = XEXP (addr, 0); | |
1011 | |
1012 switch (GET_CODE (addr)) | |
1013 { | |
1014 default: | |
1015 break; | |
1016 | |
1017 case SYMBOL_REF: | |
1018 return SYMBOL_REF_TDA_P (addr); | |
1019 | |
1020 case REG: | |
1021 return REGNO (addr) == EP_REGNUM; | |
1022 | |
1023 case PLUS: | |
1024 op0 = XEXP (addr, 0); | |
1025 op1 = XEXP (addr, 1); | |
1026 if (GET_CODE (op1) == CONST_INT | |
1027 && INTVAL (op1) < max_offset | |
1028 && INTVAL (op1) >= 0 | |
1029 && (INTVAL (op1) & mask) == 0) | |
1030 { | |
1031 if (GET_CODE (op0) == REG && REGNO (op0) == EP_REGNUM) | |
1032 return TRUE; | |
1033 | |
1034 if (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_TDA_P (op0)) | |
1035 return TRUE; | |
1036 } | |
1037 break; | |
1038 } | |
1039 | |
1040 return FALSE; | |
1041 } | |
1042 | |
1043 /* Substitute memory references involving a pointer, to use the ep pointer, | |
1044 taking care to save and preserve the ep. */ | |
1045 | |
1046 static void | |
1047 substitute_ep_register (rtx first_insn, | |
1048 rtx last_insn, | |
1049 int uses, | |
1050 int regno, | |
1051 rtx * p_r1, | |
1052 rtx * p_ep) | |
1053 { | |
1054 rtx reg = gen_rtx_REG (Pmode, regno); | |
1055 rtx insn; | |
1056 | |
1057 if (!*p_r1) | |
1058 { | |
1059 df_set_regs_ever_live (1, true); | |
1060 *p_r1 = gen_rtx_REG (Pmode, 1); | |
1061 *p_ep = gen_rtx_REG (Pmode, 30); | |
1062 } | |
1063 | |
1064 if (TARGET_DEBUG) | |
1065 fprintf (stderr, "\ | |
1066 Saved %d bytes (%d uses of register %s) in function %s, starting as insn %d, ending at %d\n", | |
1067 2 * (uses - 3), uses, reg_names[regno], | |
1068 IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), | |
1069 INSN_UID (first_insn), INSN_UID (last_insn)); | |
1070 | |
1071 if (GET_CODE (first_insn) == NOTE) | |
1072 first_insn = next_nonnote_insn (first_insn); | |
1073 | |
1074 last_insn = next_nonnote_insn (last_insn); | |
1075 for (insn = first_insn; insn && insn != last_insn; insn = NEXT_INSN (insn)) | |
1076 { | |
1077 if (GET_CODE (insn) == INSN) | |
1078 { | |
1079 rtx pattern = single_set (insn); | |
1080 | |
1081 /* Replace the memory references. */ | |
1082 if (pattern) | |
1083 { | |
1084 rtx *p_mem; | |
1085 /* Memory operands are signed by default. */ | |
1086 int unsignedp = FALSE; | |
1087 | |
1088 if (GET_CODE (SET_DEST (pattern)) == MEM | |
1089 && GET_CODE (SET_SRC (pattern)) == MEM) | |
1090 p_mem = (rtx *)0; | |
1091 | |
1092 else if (GET_CODE (SET_DEST (pattern)) == MEM) | |
1093 p_mem = &SET_DEST (pattern); | |
1094 | |
1095 else if (GET_CODE (SET_SRC (pattern)) == MEM) | |
1096 p_mem = &SET_SRC (pattern); | |
1097 | |
1098 else if (GET_CODE (SET_SRC (pattern)) == SIGN_EXTEND | |
1099 && GET_CODE (XEXP (SET_SRC (pattern), 0)) == MEM) | |
1100 p_mem = &XEXP (SET_SRC (pattern), 0); | |
1101 | |
1102 else if (GET_CODE (SET_SRC (pattern)) == ZERO_EXTEND | |
1103 && GET_CODE (XEXP (SET_SRC (pattern), 0)) == MEM) | |
1104 { | |
1105 p_mem = &XEXP (SET_SRC (pattern), 0); | |
1106 unsignedp = TRUE; | |
1107 } | |
1108 else | |
1109 p_mem = (rtx *)0; | |
1110 | |
1111 if (p_mem) | |
1112 { | |
1113 rtx addr = XEXP (*p_mem, 0); | |
1114 | |
1115 if (GET_CODE (addr) == REG && REGNO (addr) == (unsigned) regno) | |
1116 *p_mem = change_address (*p_mem, VOIDmode, *p_ep); | |
1117 | |
1118 else if (GET_CODE (addr) == PLUS | |
1119 && GET_CODE (XEXP (addr, 0)) == REG | |
1120 && REGNO (XEXP (addr, 0)) == (unsigned) regno | |
1121 && GET_CODE (XEXP (addr, 1)) == CONST_INT | |
1122 && ((INTVAL (XEXP (addr, 1))) | |
1123 < ep_memory_offset (GET_MODE (*p_mem), | |
1124 unsignedp)) | |
1125 && ((INTVAL (XEXP (addr, 1))) >= 0)) | |
1126 *p_mem = change_address (*p_mem, VOIDmode, | |
1127 gen_rtx_PLUS (Pmode, | |
1128 *p_ep, | |
1129 XEXP (addr, 1))); | |
1130 } | |
1131 } | |
1132 } | |
1133 } | |
1134 | |
1135 /* Optimize back to back cases of ep <- r1 & r1 <- ep. */ | |
1136 insn = prev_nonnote_insn (first_insn); | |
1137 if (insn && GET_CODE (insn) == INSN | |
1138 && GET_CODE (PATTERN (insn)) == SET | |
1139 && SET_DEST (PATTERN (insn)) == *p_ep | |
1140 && SET_SRC (PATTERN (insn)) == *p_r1) | |
1141 delete_insn (insn); | |
1142 else | |
1143 emit_insn_before (gen_rtx_SET (Pmode, *p_r1, *p_ep), first_insn); | |
1144 | |
1145 emit_insn_before (gen_rtx_SET (Pmode, *p_ep, reg), first_insn); | |
1146 emit_insn_before (gen_rtx_SET (Pmode, *p_ep, *p_r1), last_insn); | |
1147 } | |
1148 | |
1149 | |
1150 /* TARGET_MACHINE_DEPENDENT_REORG. On the 850, we use it to implement | |
1151 the -mep mode to copy heavily used pointers to ep to use the implicit | |
1152 addressing. */ | |
1153 | |
1154 static void | |
1155 v850_reorg (void) | |
1156 { | |
1157 struct | |
1158 { | |
1159 int uses; | |
1160 rtx first_insn; | |
1161 rtx last_insn; | |
1162 } | |
1163 regs[FIRST_PSEUDO_REGISTER]; | |
1164 | |
1165 int i; | |
1166 int use_ep = FALSE; | |
1167 rtx r1 = NULL_RTX; | |
1168 rtx ep = NULL_RTX; | |
1169 rtx insn; | |
1170 rtx pattern; | |
1171 | |
1172 /* If not ep mode, just return now. */ | |
1173 if (!TARGET_EP) | |
1174 return; | |
1175 | |
1176 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1177 { | |
1178 regs[i].uses = 0; | |
1179 regs[i].first_insn = NULL_RTX; | |
1180 regs[i].last_insn = NULL_RTX; | |
1181 } | |
1182 | |
1183 for (insn = get_insns (); insn != NULL_RTX; insn = NEXT_INSN (insn)) | |
1184 { | |
1185 switch (GET_CODE (insn)) | |
1186 { | |
1187 /* End of basic block */ | |
1188 default: | |
1189 if (!use_ep) | |
1190 { | |
1191 int max_uses = -1; | |
1192 int max_regno = -1; | |
1193 | |
1194 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1195 { | |
1196 if (max_uses < regs[i].uses) | |
1197 { | |
1198 max_uses = regs[i].uses; | |
1199 max_regno = i; | |
1200 } | |
1201 } | |
1202 | |
1203 if (max_uses > 3) | |
1204 substitute_ep_register (regs[max_regno].first_insn, | |
1205 regs[max_regno].last_insn, | |
1206 max_uses, max_regno, &r1, &ep); | |
1207 } | |
1208 | |
1209 use_ep = FALSE; | |
1210 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1211 { | |
1212 regs[i].uses = 0; | |
1213 regs[i].first_insn = NULL_RTX; | |
1214 regs[i].last_insn = NULL_RTX; | |
1215 } | |
1216 break; | |
1217 | |
1218 case NOTE: | |
1219 break; | |
1220 | |
1221 case INSN: | |
1222 pattern = single_set (insn); | |
1223 | |
1224 /* See if there are any memory references we can shorten */ | |
1225 if (pattern) | |
1226 { | |
1227 rtx src = SET_SRC (pattern); | |
1228 rtx dest = SET_DEST (pattern); | |
1229 rtx mem; | |
1230 /* Memory operands are signed by default. */ | |
1231 int unsignedp = FALSE; | |
1232 | |
1233 /* We might have (SUBREG (MEM)) here, so just get rid of the | |
1234 subregs to make this code simpler. */ | |
1235 if (GET_CODE (dest) == SUBREG | |
1236 && (GET_CODE (SUBREG_REG (dest)) == MEM | |
1237 || GET_CODE (SUBREG_REG (dest)) == REG)) | |
1238 alter_subreg (&dest); | |
1239 if (GET_CODE (src) == SUBREG | |
1240 && (GET_CODE (SUBREG_REG (src)) == MEM | |
1241 || GET_CODE (SUBREG_REG (src)) == REG)) | |
1242 alter_subreg (&src); | |
1243 | |
1244 if (GET_CODE (dest) == MEM && GET_CODE (src) == MEM) | |
1245 mem = NULL_RTX; | |
1246 | |
1247 else if (GET_CODE (dest) == MEM) | |
1248 mem = dest; | |
1249 | |
1250 else if (GET_CODE (src) == MEM) | |
1251 mem = src; | |
1252 | |
1253 else if (GET_CODE (src) == SIGN_EXTEND | |
1254 && GET_CODE (XEXP (src, 0)) == MEM) | |
1255 mem = XEXP (src, 0); | |
1256 | |
1257 else if (GET_CODE (src) == ZERO_EXTEND | |
1258 && GET_CODE (XEXP (src, 0)) == MEM) | |
1259 { | |
1260 mem = XEXP (src, 0); | |
1261 unsignedp = TRUE; | |
1262 } | |
1263 else | |
1264 mem = NULL_RTX; | |
1265 | |
1266 if (mem && ep_memory_operand (mem, GET_MODE (mem), unsignedp)) | |
1267 use_ep = TRUE; | |
1268 | |
1269 else if (!use_ep && mem | |
1270 && GET_MODE_SIZE (GET_MODE (mem)) <= UNITS_PER_WORD) | |
1271 { | |
1272 rtx addr = XEXP (mem, 0); | |
1273 int regno = -1; | |
1274 int short_p; | |
1275 | |
1276 if (GET_CODE (addr) == REG) | |
1277 { | |
1278 short_p = TRUE; | |
1279 regno = REGNO (addr); | |
1280 } | |
1281 | |
1282 else if (GET_CODE (addr) == PLUS | |
1283 && GET_CODE (XEXP (addr, 0)) == REG | |
1284 && GET_CODE (XEXP (addr, 1)) == CONST_INT | |
1285 && ((INTVAL (XEXP (addr, 1))) | |
1286 < ep_memory_offset (GET_MODE (mem), unsignedp)) | |
1287 && ((INTVAL (XEXP (addr, 1))) >= 0)) | |
1288 { | |
1289 short_p = TRUE; | |
1290 regno = REGNO (XEXP (addr, 0)); | |
1291 } | |
1292 | |
1293 else | |
1294 short_p = FALSE; | |
1295 | |
1296 if (short_p) | |
1297 { | |
1298 regs[regno].uses++; | |
1299 regs[regno].last_insn = insn; | |
1300 if (!regs[regno].first_insn) | |
1301 regs[regno].first_insn = insn; | |
1302 } | |
1303 } | |
1304 | |
1305 /* Loading up a register in the basic block zaps any savings | |
1306 for the register */ | |
1307 if (GET_CODE (dest) == REG) | |
1308 { | |
1309 enum machine_mode mode = GET_MODE (dest); | |
1310 int regno; | |
1311 int endregno; | |
1312 | |
1313 regno = REGNO (dest); | |
1314 endregno = regno + HARD_REGNO_NREGS (regno, mode); | |
1315 | |
1316 if (!use_ep) | |
1317 { | |
1318 /* See if we can use the pointer before this | |
1319 modification. */ | |
1320 int max_uses = -1; | |
1321 int max_regno = -1; | |
1322 | |
1323 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1324 { | |
1325 if (max_uses < regs[i].uses) | |
1326 { | |
1327 max_uses = regs[i].uses; | |
1328 max_regno = i; | |
1329 } | |
1330 } | |
1331 | |
1332 if (max_uses > 3 | |
1333 && max_regno >= regno | |
1334 && max_regno < endregno) | |
1335 { | |
1336 substitute_ep_register (regs[max_regno].first_insn, | |
1337 regs[max_regno].last_insn, | |
1338 max_uses, max_regno, &r1, | |
1339 &ep); | |
1340 | |
1341 /* Since we made a substitution, zap all remembered | |
1342 registers. */ | |
1343 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1344 { | |
1345 regs[i].uses = 0; | |
1346 regs[i].first_insn = NULL_RTX; | |
1347 regs[i].last_insn = NULL_RTX; | |
1348 } | |
1349 } | |
1350 } | |
1351 | |
1352 for (i = regno; i < endregno; i++) | |
1353 { | |
1354 regs[i].uses = 0; | |
1355 regs[i].first_insn = NULL_RTX; | |
1356 regs[i].last_insn = NULL_RTX; | |
1357 } | |
1358 } | |
1359 } | |
1360 } | |
1361 } | |
1362 } | |
1363 | |
1364 | |
1365 /* # of registers saved by the interrupt handler. */ | |
1366 #define INTERRUPT_FIXED_NUM 4 | |
1367 | |
1368 /* # of bytes for registers saved by the interrupt handler. */ | |
1369 #define INTERRUPT_FIXED_SAVE_SIZE (4 * INTERRUPT_FIXED_NUM) | |
1370 | |
1371 /* # of registers saved in register parameter area. */ | |
1372 #define INTERRUPT_REGPARM_NUM 4 | |
1373 /* # of words saved for other registers. */ | |
1374 #define INTERRUPT_ALL_SAVE_NUM \ | |
1375 (30 - INTERRUPT_FIXED_NUM + INTERRUPT_REGPARM_NUM) | |
1376 | |
1377 #define INTERRUPT_ALL_SAVE_SIZE (4 * INTERRUPT_ALL_SAVE_NUM) | |
1378 | |
1379 int | |
1380 compute_register_save_size (long * p_reg_saved) | |
1381 { | |
1382 int size = 0; | |
1383 int i; | |
1384 int interrupt_handler = v850_interrupt_function_p (current_function_decl); | |
1385 int call_p = df_regs_ever_live_p (LINK_POINTER_REGNUM); | |
1386 long reg_saved = 0; | |
1387 | |
1388 /* Count the return pointer if we need to save it. */ | |
1389 if (crtl->profile && !call_p) | |
1390 { | |
1391 df_set_regs_ever_live (LINK_POINTER_REGNUM, true); | |
1392 call_p = 1; | |
1393 } | |
1394 | |
1395 /* Count space for the register saves. */ | |
1396 if (interrupt_handler) | |
1397 { | |
1398 for (i = 0; i <= 31; i++) | |
1399 switch (i) | |
1400 { | |
1401 default: | |
1402 if (df_regs_ever_live_p (i) || call_p) | |
1403 { | |
1404 size += 4; | |
1405 reg_saved |= 1L << i; | |
1406 } | |
1407 break; | |
1408 | |
1409 /* We don't save/restore r0 or the stack pointer */ | |
1410 case 0: | |
1411 case STACK_POINTER_REGNUM: | |
1412 break; | |
1413 | |
1414 /* For registers with fixed use, we save them, set them to the | |
1415 appropriate value, and then restore them. | |
1416 These registers are handled specially, so don't list them | |
1417 on the list of registers to save in the prologue. */ | |
1418 case 1: /* temp used to hold ep */ | |
1419 case 4: /* gp */ | |
1420 case 10: /* temp used to call interrupt save/restore */ | |
1421 case EP_REGNUM: /* ep */ | |
1422 size += 4; | |
1423 break; | |
1424 } | |
1425 } | |
1426 else | |
1427 { | |
1428 /* Find the first register that needs to be saved. */ | |
1429 for (i = 0; i <= 31; i++) | |
1430 if (df_regs_ever_live_p (i) && ((! call_used_regs[i]) | |
1431 || i == LINK_POINTER_REGNUM)) | |
1432 break; | |
1433 | |
1434 /* If it is possible that an out-of-line helper function might be | |
1435 used to generate the prologue for the current function, then we | |
1436 need to cover the possibility that such a helper function will | |
1437 be used, despite the fact that there might be gaps in the list of | |
1438 registers that need to be saved. To detect this we note that the | |
1439 helper functions always push at least register r29 (provided | |
1440 that the function is not an interrupt handler). */ | |
1441 | |
1442 if (TARGET_PROLOG_FUNCTION | |
1443 && (i == 2 || ((i >= 20) && (i < 30)))) | |
1444 { | |
1445 if (i == 2) | |
1446 { | |
1447 size += 4; | |
1448 reg_saved |= 1L << i; | |
1449 | |
1450 i = 20; | |
1451 } | |
1452 | |
1453 /* Helper functions save all registers between the starting | |
1454 register and the last register, regardless of whether they | |
1455 are actually used by the function or not. */ | |
1456 for (; i <= 29; i++) | |
1457 { | |
1458 size += 4; | |
1459 reg_saved |= 1L << i; | |
1460 } | |
1461 | |
1462 if (df_regs_ever_live_p (LINK_POINTER_REGNUM)) | |
1463 { | |
1464 size += 4; | |
1465 reg_saved |= 1L << LINK_POINTER_REGNUM; | |
1466 } | |
1467 } | |
1468 else | |
1469 { | |
1470 for (; i <= 31; i++) | |
1471 if (df_regs_ever_live_p (i) && ((! call_used_regs[i]) | |
1472 || i == LINK_POINTER_REGNUM)) | |
1473 { | |
1474 size += 4; | |
1475 reg_saved |= 1L << i; | |
1476 } | |
1477 } | |
1478 } | |
1479 | |
1480 if (p_reg_saved) | |
1481 *p_reg_saved = reg_saved; | |
1482 | |
1483 return size; | |
1484 } | |
1485 | |
1486 int | |
1487 compute_frame_size (int size, long * p_reg_saved) | |
1488 { | |
1489 return (size | |
1490 + compute_register_save_size (p_reg_saved) | |
1491 + crtl->outgoing_args_size); | |
1492 } | |
1493 | |
1494 | |
1495 void | |
1496 expand_prologue (void) | |
1497 { | |
1498 unsigned int i; | |
1499 int offset; | |
1500 unsigned int size = get_frame_size (); | |
1501 unsigned int actual_fsize; | |
1502 unsigned int init_stack_alloc = 0; | |
1503 rtx save_regs[32]; | |
1504 rtx save_all; | |
1505 unsigned int num_save; | |
1506 unsigned int default_stack; | |
1507 int code; | |
1508 int interrupt_handler = v850_interrupt_function_p (current_function_decl); | |
1509 long reg_saved = 0; | |
1510 | |
1511 actual_fsize = compute_frame_size (size, ®_saved); | |
1512 | |
1513 /* Save/setup global registers for interrupt functions right now. */ | |
1514 if (interrupt_handler) | |
1515 { | |
1516 if (TARGET_V850E && ! TARGET_DISABLE_CALLT) | |
1517 emit_insn (gen_callt_save_interrupt ()); | |
1518 else | |
1519 emit_insn (gen_save_interrupt ()); | |
1520 | |
1521 actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE; | |
1522 | |
1523 if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) | |
1524 actual_fsize -= INTERRUPT_ALL_SAVE_SIZE; | |
1525 } | |
1526 | |
1527 /* Save arg registers to the stack if necessary. */ | |
1528 else if (crtl->args.info.anonymous_args) | |
1529 { | |
1530 if (TARGET_PROLOG_FUNCTION && TARGET_V850E && !TARGET_DISABLE_CALLT) | |
1531 emit_insn (gen_save_r6_r9_v850e ()); | |
1532 else if (TARGET_PROLOG_FUNCTION && ! TARGET_LONG_CALLS) | |
1533 emit_insn (gen_save_r6_r9 ()); | |
1534 else | |
1535 { | |
1536 offset = 0; | |
1537 for (i = 6; i < 10; i++) | |
1538 { | |
1539 emit_move_insn (gen_rtx_MEM (SImode, | |
1540 plus_constant (stack_pointer_rtx, | |
1541 offset)), | |
1542 gen_rtx_REG (SImode, i)); | |
1543 offset += 4; | |
1544 } | |
1545 } | |
1546 } | |
1547 | |
1548 /* Identify all of the saved registers. */ | |
1549 num_save = 0; | |
1550 default_stack = 0; | |
1551 for (i = 1; i < 31; i++) | |
1552 { | |
1553 if (((1L << i) & reg_saved) != 0) | |
1554 save_regs[num_save++] = gen_rtx_REG (Pmode, i); | |
1555 } | |
1556 | |
1557 /* If the return pointer is saved, the helper functions also allocate | |
1558 16 bytes of stack for arguments to be saved in. */ | |
1559 if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) | |
1560 { | |
1561 save_regs[num_save++] = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM); | |
1562 default_stack = 16; | |
1563 } | |
1564 | |
1565 /* See if we have an insn that allocates stack space and saves the particular | |
1566 registers we want to. */ | |
1567 save_all = NULL_RTX; | |
1568 if (TARGET_PROLOG_FUNCTION && num_save > 0 && actual_fsize >= default_stack) | |
1569 { | |
1570 int alloc_stack = (4 * num_save) + default_stack; | |
1571 int unalloc_stack = actual_fsize - alloc_stack; | |
1572 int save_func_len = 4; | |
1573 int save_normal_len; | |
1574 | |
1575 if (unalloc_stack) | |
1576 save_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4; | |
1577 | |
1578 /* see if we would have used ep to save the stack */ | |
1579 if (TARGET_EP && num_save > 3 && (unsigned)actual_fsize < 255) | |
1580 save_normal_len = (3 * 2) + (2 * num_save); | |
1581 else | |
1582 save_normal_len = 4 * num_save; | |
1583 | |
1584 save_normal_len += CONST_OK_FOR_J (actual_fsize) ? 2 : 4; | |
1585 | |
1586 /* Don't bother checking if we don't actually save any space. | |
1587 This happens for instance if one register is saved and additional | |
1588 stack space is allocated. */ | |
1589 if (save_func_len < save_normal_len) | |
1590 { | |
1591 save_all = gen_rtx_PARALLEL | |
1592 (VOIDmode, | |
1593 rtvec_alloc (num_save + 1 | |
1594 + (TARGET_V850 ? (TARGET_LONG_CALLS ? 2 : 1) : 0))); | |
1595 | |
1596 XVECEXP (save_all, 0, 0) | |
1597 = gen_rtx_SET (VOIDmode, | |
1598 stack_pointer_rtx, | |
1599 plus_constant (stack_pointer_rtx, -alloc_stack)); | |
1600 | |
1601 offset = - default_stack; | |
1602 for (i = 0; i < num_save; i++) | |
1603 { | |
1604 XVECEXP (save_all, 0, i+1) | |
1605 = gen_rtx_SET (VOIDmode, | |
1606 gen_rtx_MEM (Pmode, | |
1607 plus_constant (stack_pointer_rtx, | |
1608 offset)), | |
1609 save_regs[i]); | |
1610 offset -= 4; | |
1611 } | |
1612 | |
1613 if (TARGET_V850) | |
1614 { | |
1615 XVECEXP (save_all, 0, num_save + 1) | |
1616 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 10)); | |
1617 | |
1618 if (TARGET_LONG_CALLS) | |
1619 XVECEXP (save_all, 0, num_save + 2) | |
1620 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11)); | |
1621 } | |
1622 | |
1623 code = recog (save_all, NULL_RTX, NULL); | |
1624 if (code >= 0) | |
1625 { | |
1626 rtx insn = emit_insn (save_all); | |
1627 INSN_CODE (insn) = code; | |
1628 actual_fsize -= alloc_stack; | |
1629 | |
1630 if (TARGET_DEBUG) | |
1631 fprintf (stderr, "\ | |
1632 Saved %d bytes via prologue function (%d vs. %d) for function %s\n", | |
1633 save_normal_len - save_func_len, | |
1634 save_normal_len, save_func_len, | |
1635 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))); | |
1636 } | |
1637 else | |
1638 save_all = NULL_RTX; | |
1639 } | |
1640 } | |
1641 | |
1642 /* If no prolog save function is available, store the registers the old | |
1643 fashioned way (one by one). */ | |
1644 if (!save_all) | |
1645 { | |
1646 /* Special case interrupt functions that save all registers for a call. */ | |
1647 if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) | |
1648 { | |
1649 if (TARGET_V850E && ! TARGET_DISABLE_CALLT) | |
1650 emit_insn (gen_callt_save_all_interrupt ()); | |
1651 else | |
1652 emit_insn (gen_save_all_interrupt ()); | |
1653 } | |
1654 else | |
1655 { | |
1656 /* If the stack is too big, allocate it in chunks so we can do the | |
1657 register saves. We use the register save size so we use the ep | |
1658 register. */ | |
1659 if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize)) | |
1660 init_stack_alloc = compute_register_save_size (NULL); | |
1661 else | |
1662 init_stack_alloc = actual_fsize; | |
1663 | |
1664 /* Save registers at the beginning of the stack frame. */ | |
1665 offset = init_stack_alloc - 4; | |
1666 | |
1667 if (init_stack_alloc) | |
1668 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1669 stack_pointer_rtx, | |
1670 GEN_INT (- (signed) init_stack_alloc))); | |
1671 | |
1672 /* Save the return pointer first. */ | |
1673 if (num_save > 0 && REGNO (save_regs[num_save-1]) == LINK_POINTER_REGNUM) | |
1674 { | |
1675 emit_move_insn (gen_rtx_MEM (SImode, | |
1676 plus_constant (stack_pointer_rtx, | |
1677 offset)), | |
1678 save_regs[--num_save]); | |
1679 offset -= 4; | |
1680 } | |
1681 | |
1682 for (i = 0; i < num_save; i++) | |
1683 { | |
1684 emit_move_insn (gen_rtx_MEM (SImode, | |
1685 plus_constant (stack_pointer_rtx, | |
1686 offset)), | |
1687 save_regs[i]); | |
1688 offset -= 4; | |
1689 } | |
1690 } | |
1691 } | |
1692 | |
1693 /* Allocate the rest of the stack that was not allocated above (either it is | |
1694 > 32K or we just called a function to save the registers and needed more | |
1695 stack. */ | |
1696 if (actual_fsize > init_stack_alloc) | |
1697 { | |
1698 int diff = actual_fsize - init_stack_alloc; | |
1699 if (CONST_OK_FOR_K (diff)) | |
1700 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1701 stack_pointer_rtx, | |
1702 GEN_INT (-diff))); | |
1703 else | |
1704 { | |
1705 rtx reg = gen_rtx_REG (Pmode, 12); | |
1706 emit_move_insn (reg, GEN_INT (-diff)); | |
1707 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg)); | |
1708 } | |
1709 } | |
1710 | |
1711 /* If we need a frame pointer, set it up now. */ | |
1712 if (frame_pointer_needed) | |
1713 emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); | |
1714 } | |
1715 | |
1716 | |
1717 void | |
1718 expand_epilogue (void) | |
1719 { | |
1720 unsigned int i; | |
1721 int offset; | |
1722 unsigned int size = get_frame_size (); | |
1723 long reg_saved = 0; | |
1724 int actual_fsize = compute_frame_size (size, ®_saved); | |
1725 unsigned int init_stack_free = 0; | |
1726 rtx restore_regs[32]; | |
1727 rtx restore_all; | |
1728 unsigned int num_restore; | |
1729 unsigned int default_stack; | |
1730 int code; | |
1731 int interrupt_handler = v850_interrupt_function_p (current_function_decl); | |
1732 | |
1733 /* Eliminate the initial stack stored by interrupt functions. */ | |
1734 if (interrupt_handler) | |
1735 { | |
1736 actual_fsize -= INTERRUPT_FIXED_SAVE_SIZE; | |
1737 if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) | |
1738 actual_fsize -= INTERRUPT_ALL_SAVE_SIZE; | |
1739 } | |
1740 | |
1741 /* Cut off any dynamic stack created. */ | |
1742 if (frame_pointer_needed) | |
1743 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); | |
1744 | |
1745 /* Identify all of the saved registers. */ | |
1746 num_restore = 0; | |
1747 default_stack = 0; | |
1748 for (i = 1; i < 31; i++) | |
1749 { | |
1750 if (((1L << i) & reg_saved) != 0) | |
1751 restore_regs[num_restore++] = gen_rtx_REG (Pmode, i); | |
1752 } | |
1753 | |
1754 /* If the return pointer is saved, the helper functions also allocate | |
1755 16 bytes of stack for arguments to be saved in. */ | |
1756 if (((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) | |
1757 { | |
1758 restore_regs[num_restore++] = gen_rtx_REG (Pmode, LINK_POINTER_REGNUM); | |
1759 default_stack = 16; | |
1760 } | |
1761 | |
1762 /* See if we have an insn that restores the particular registers we | |
1763 want to. */ | |
1764 restore_all = NULL_RTX; | |
1765 | |
1766 if (TARGET_PROLOG_FUNCTION | |
1767 && num_restore > 0 | |
1768 && actual_fsize >= (signed) default_stack | |
1769 && !interrupt_handler) | |
1770 { | |
1771 int alloc_stack = (4 * num_restore) + default_stack; | |
1772 int unalloc_stack = actual_fsize - alloc_stack; | |
1773 int restore_func_len = 4; | |
1774 int restore_normal_len; | |
1775 | |
1776 if (unalloc_stack) | |
1777 restore_func_len += CONST_OK_FOR_J (unalloc_stack) ? 2 : 4; | |
1778 | |
1779 /* See if we would have used ep to restore the registers. */ | |
1780 if (TARGET_EP && num_restore > 3 && (unsigned)actual_fsize < 255) | |
1781 restore_normal_len = (3 * 2) + (2 * num_restore); | |
1782 else | |
1783 restore_normal_len = 4 * num_restore; | |
1784 | |
1785 restore_normal_len += (CONST_OK_FOR_J (actual_fsize) ? 2 : 4) + 2; | |
1786 | |
1787 /* Don't bother checking if we don't actually save any space. */ | |
1788 if (restore_func_len < restore_normal_len) | |
1789 { | |
1790 restore_all = gen_rtx_PARALLEL (VOIDmode, | |
1791 rtvec_alloc (num_restore + 2)); | |
1792 XVECEXP (restore_all, 0, 0) = gen_rtx_RETURN (VOIDmode); | |
1793 XVECEXP (restore_all, 0, 1) | |
1794 = gen_rtx_SET (VOIDmode, stack_pointer_rtx, | |
1795 gen_rtx_PLUS (Pmode, | |
1796 stack_pointer_rtx, | |
1797 GEN_INT (alloc_stack))); | |
1798 | |
1799 offset = alloc_stack - 4; | |
1800 for (i = 0; i < num_restore; i++) | |
1801 { | |
1802 XVECEXP (restore_all, 0, i+2) | |
1803 = gen_rtx_SET (VOIDmode, | |
1804 restore_regs[i], | |
1805 gen_rtx_MEM (Pmode, | |
1806 plus_constant (stack_pointer_rtx, | |
1807 offset))); | |
1808 offset -= 4; | |
1809 } | |
1810 | |
1811 code = recog (restore_all, NULL_RTX, NULL); | |
1812 | |
1813 if (code >= 0) | |
1814 { | |
1815 rtx insn; | |
1816 | |
1817 actual_fsize -= alloc_stack; | |
1818 if (actual_fsize) | |
1819 { | |
1820 if (CONST_OK_FOR_K (actual_fsize)) | |
1821 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1822 stack_pointer_rtx, | |
1823 GEN_INT (actual_fsize))); | |
1824 else | |
1825 { | |
1826 rtx reg = gen_rtx_REG (Pmode, 12); | |
1827 emit_move_insn (reg, GEN_INT (actual_fsize)); | |
1828 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1829 stack_pointer_rtx, | |
1830 reg)); | |
1831 } | |
1832 } | |
1833 | |
1834 insn = emit_jump_insn (restore_all); | |
1835 INSN_CODE (insn) = code; | |
1836 | |
1837 if (TARGET_DEBUG) | |
1838 fprintf (stderr, "\ | |
1839 Saved %d bytes via epilogue function (%d vs. %d) in function %s\n", | |
1840 restore_normal_len - restore_func_len, | |
1841 restore_normal_len, restore_func_len, | |
1842 IDENTIFIER_POINTER (DECL_NAME (current_function_decl))); | |
1843 } | |
1844 else | |
1845 restore_all = NULL_RTX; | |
1846 } | |
1847 } | |
1848 | |
1849 /* If no epilogue save function is available, restore the registers the | |
1850 old fashioned way (one by one). */ | |
1851 if (!restore_all) | |
1852 { | |
1853 /* If the stack is large, we need to cut it down in 2 pieces. */ | |
1854 if (actual_fsize && !CONST_OK_FOR_K (-actual_fsize)) | |
1855 init_stack_free = 4 * num_restore; | |
1856 else | |
1857 init_stack_free = (signed) actual_fsize; | |
1858 | |
1859 /* Deallocate the rest of the stack if it is > 32K. */ | |
1860 if (actual_fsize > init_stack_free) | |
1861 { | |
1862 int diff; | |
1863 | |
1864 diff = actual_fsize - ((interrupt_handler) ? 0 : init_stack_free); | |
1865 | |
1866 if (CONST_OK_FOR_K (diff)) | |
1867 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1868 stack_pointer_rtx, | |
1869 GEN_INT (diff))); | |
1870 else | |
1871 { | |
1872 rtx reg = gen_rtx_REG (Pmode, 12); | |
1873 emit_move_insn (reg, GEN_INT (diff)); | |
1874 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1875 stack_pointer_rtx, | |
1876 reg)); | |
1877 } | |
1878 } | |
1879 | |
1880 /* Special case interrupt functions that save all registers | |
1881 for a call. */ | |
1882 if (interrupt_handler && ((1L << LINK_POINTER_REGNUM) & reg_saved) != 0) | |
1883 { | |
1884 if (TARGET_V850E && ! TARGET_DISABLE_CALLT) | |
1885 emit_insn (gen_callt_restore_all_interrupt ()); | |
1886 else | |
1887 emit_insn (gen_restore_all_interrupt ()); | |
1888 } | |
1889 else | |
1890 { | |
1891 /* Restore registers from the beginning of the stack frame. */ | |
1892 offset = init_stack_free - 4; | |
1893 | |
1894 /* Restore the return pointer first. */ | |
1895 if (num_restore > 0 | |
1896 && REGNO (restore_regs [num_restore - 1]) == LINK_POINTER_REGNUM) | |
1897 { | |
1898 emit_move_insn (restore_regs[--num_restore], | |
1899 gen_rtx_MEM (SImode, | |
1900 plus_constant (stack_pointer_rtx, | |
1901 offset))); | |
1902 offset -= 4; | |
1903 } | |
1904 | |
1905 for (i = 0; i < num_restore; i++) | |
1906 { | |
1907 emit_move_insn (restore_regs[i], | |
1908 gen_rtx_MEM (SImode, | |
1909 plus_constant (stack_pointer_rtx, | |
1910 offset))); | |
1911 | |
1912 emit_use (restore_regs[i]); | |
1913 offset -= 4; | |
1914 } | |
1915 | |
1916 /* Cut back the remainder of the stack. */ | |
1917 if (init_stack_free) | |
1918 emit_insn (gen_addsi3 (stack_pointer_rtx, | |
1919 stack_pointer_rtx, | |
1920 GEN_INT (init_stack_free))); | |
1921 } | |
1922 | |
1923 /* And return or use reti for interrupt handlers. */ | |
1924 if (interrupt_handler) | |
1925 { | |
1926 if (TARGET_V850E && ! TARGET_DISABLE_CALLT) | |
1927 emit_insn (gen_callt_return_interrupt ()); | |
1928 else | |
1929 emit_jump_insn (gen_return_interrupt ()); | |
1930 } | |
1931 else if (actual_fsize) | |
1932 emit_jump_insn (gen_return_internal ()); | |
1933 else | |
1934 emit_jump_insn (gen_return ()); | |
1935 } | |
1936 | |
1937 v850_interrupt_cache_p = FALSE; | |
1938 v850_interrupt_p = FALSE; | |
1939 } | |
1940 | |
1941 | |
1942 /* Update the condition code from the insn. */ | |
1943 | |
1944 void | |
1945 notice_update_cc (rtx body, rtx insn) | |
1946 { | |
1947 switch (get_attr_cc (insn)) | |
1948 { | |
1949 case CC_NONE: | |
1950 /* Insn does not affect CC at all. */ | |
1951 break; | |
1952 | |
1953 case CC_NONE_0HIT: | |
1954 /* Insn does not change CC, but the 0'th operand has been changed. */ | |
1955 if (cc_status.value1 != 0 | |
1956 && reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1)) | |
1957 cc_status.value1 = 0; | |
1958 break; | |
1959 | |
1960 case CC_SET_ZN: | |
1961 /* Insn sets the Z,N flags of CC to recog_data.operand[0]. | |
1962 V,C is in an unusable state. */ | |
1963 CC_STATUS_INIT; | |
1964 cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY; | |
1965 cc_status.value1 = recog_data.operand[0]; | |
1966 break; | |
1967 | |
1968 case CC_SET_ZNV: | |
1969 /* Insn sets the Z,N,V flags of CC to recog_data.operand[0]. | |
1970 C is in an unusable state. */ | |
1971 CC_STATUS_INIT; | |
1972 cc_status.flags |= CC_NO_CARRY; | |
1973 cc_status.value1 = recog_data.operand[0]; | |
1974 break; | |
1975 | |
1976 case CC_COMPARE: | |
1977 /* The insn is a compare instruction. */ | |
1978 CC_STATUS_INIT; | |
1979 cc_status.value1 = SET_SRC (body); | |
1980 break; | |
1981 | |
1982 case CC_CLOBBER: | |
1983 /* Insn doesn't leave CC in a usable state. */ | |
1984 CC_STATUS_INIT; | |
1985 break; | |
1986 } | |
1987 } | |
1988 | |
1989 /* Retrieve the data area that has been chosen for the given decl. */ | |
1990 | |
1991 v850_data_area | |
1992 v850_get_data_area (tree decl) | |
1993 { | |
1994 if (lookup_attribute ("sda", DECL_ATTRIBUTES (decl)) != NULL_TREE) | |
1995 return DATA_AREA_SDA; | |
1996 | |
1997 if (lookup_attribute ("tda", DECL_ATTRIBUTES (decl)) != NULL_TREE) | |
1998 return DATA_AREA_TDA; | |
1999 | |
2000 if (lookup_attribute ("zda", DECL_ATTRIBUTES (decl)) != NULL_TREE) | |
2001 return DATA_AREA_ZDA; | |
2002 | |
2003 return DATA_AREA_NORMAL; | |
2004 } | |
2005 | |
2006 /* Store the indicated data area in the decl's attributes. */ | |
2007 | |
2008 static void | |
2009 v850_set_data_area (tree decl, v850_data_area data_area) | |
2010 { | |
2011 tree name; | |
2012 | |
2013 switch (data_area) | |
2014 { | |
2015 case DATA_AREA_SDA: name = get_identifier ("sda"); break; | |
2016 case DATA_AREA_TDA: name = get_identifier ("tda"); break; | |
2017 case DATA_AREA_ZDA: name = get_identifier ("zda"); break; | |
2018 default: | |
2019 return; | |
2020 } | |
2021 | |
2022 DECL_ATTRIBUTES (decl) = tree_cons | |
2023 (name, NULL, DECL_ATTRIBUTES (decl)); | |
2024 } | |
2025 | |
2026 const struct attribute_spec v850_attribute_table[] = | |
2027 { | |
2028 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ | |
2029 { "interrupt_handler", 0, 0, true, false, false, v850_handle_interrupt_attribute }, | |
2030 { "interrupt", 0, 0, true, false, false, v850_handle_interrupt_attribute }, | |
2031 { "sda", 0, 0, true, false, false, v850_handle_data_area_attribute }, | |
2032 { "tda", 0, 0, true, false, false, v850_handle_data_area_attribute }, | |
2033 { "zda", 0, 0, true, false, false, v850_handle_data_area_attribute }, | |
2034 { NULL, 0, 0, false, false, false, NULL } | |
2035 }; | |
2036 | |
2037 /* Handle an "interrupt" attribute; arguments as in | |
2038 struct attribute_spec.handler. */ | |
2039 static tree | |
2040 v850_handle_interrupt_attribute (tree * node, | |
2041 tree name, | |
2042 tree args ATTRIBUTE_UNUSED, | |
2043 int flags ATTRIBUTE_UNUSED, | |
2044 bool * no_add_attrs) | |
2045 { | |
2046 if (TREE_CODE (*node) != FUNCTION_DECL) | |
2047 { | |
2048 warning (OPT_Wattributes, "%qs attribute only applies to functions", | |
2049 IDENTIFIER_POINTER (name)); | |
2050 *no_add_attrs = true; | |
2051 } | |
2052 | |
2053 return NULL_TREE; | |
2054 } | |
2055 | |
2056 /* Handle a "sda", "tda" or "zda" attribute; arguments as in | |
2057 struct attribute_spec.handler. */ | |
2058 static tree | |
2059 v850_handle_data_area_attribute (tree* node, | |
2060 tree name, | |
2061 tree args ATTRIBUTE_UNUSED, | |
2062 int flags ATTRIBUTE_UNUSED, | |
2063 bool * no_add_attrs) | |
2064 { | |
2065 v850_data_area data_area; | |
2066 v850_data_area area; | |
2067 tree decl = *node; | |
2068 | |
2069 /* Implement data area attribute. */ | |
2070 if (is_attribute_p ("sda", name)) | |
2071 data_area = DATA_AREA_SDA; | |
2072 else if (is_attribute_p ("tda", name)) | |
2073 data_area = DATA_AREA_TDA; | |
2074 else if (is_attribute_p ("zda", name)) | |
2075 data_area = DATA_AREA_ZDA; | |
2076 else | |
2077 gcc_unreachable (); | |
2078 | |
2079 switch (TREE_CODE (decl)) | |
2080 { | |
2081 case VAR_DECL: | |
2082 if (current_function_decl != NULL_TREE) | |
2083 { | |
2084 error ("%Jdata area attributes cannot be specified for " | |
2085 "local variables", decl); | |
2086 *no_add_attrs = true; | |
2087 } | |
2088 | |
2089 /* Drop through. */ | |
2090 | |
2091 case FUNCTION_DECL: | |
2092 area = v850_get_data_area (decl); | |
2093 if (area != DATA_AREA_NORMAL && data_area != area) | |
2094 { | |
2095 error ("data area of %q+D conflicts with previous declaration", | |
2096 decl); | |
2097 *no_add_attrs = true; | |
2098 } | |
2099 break; | |
2100 | |
2101 default: | |
2102 break; | |
2103 } | |
2104 | |
2105 return NULL_TREE; | |
2106 } | |
2107 | |
2108 | |
2109 /* Return nonzero if FUNC is an interrupt function as specified | |
2110 by the "interrupt" attribute. */ | |
2111 | |
2112 int | |
2113 v850_interrupt_function_p (tree func) | |
2114 { | |
2115 tree a; | |
2116 int ret = 0; | |
2117 | |
2118 if (v850_interrupt_cache_p) | |
2119 return v850_interrupt_p; | |
2120 | |
2121 if (TREE_CODE (func) != FUNCTION_DECL) | |
2122 return 0; | |
2123 | |
2124 a = lookup_attribute ("interrupt_handler", DECL_ATTRIBUTES (func)); | |
2125 if (a != NULL_TREE) | |
2126 ret = 1; | |
2127 | |
2128 else | |
2129 { | |
2130 a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func)); | |
2131 ret = a != NULL_TREE; | |
2132 } | |
2133 | |
2134 /* Its not safe to trust global variables until after function inlining has | |
2135 been done. */ | |
2136 if (reload_completed | reload_in_progress) | |
2137 v850_interrupt_p = ret; | |
2138 | |
2139 return ret; | |
2140 } | |
2141 | |
2142 | |
2143 static void | |
2144 v850_encode_data_area (tree decl, rtx symbol) | |
2145 { | |
2146 int flags; | |
2147 | |
2148 /* Map explicit sections into the appropriate attribute */ | |
2149 if (v850_get_data_area (decl) == DATA_AREA_NORMAL) | |
2150 { | |
2151 if (DECL_SECTION_NAME (decl)) | |
2152 { | |
2153 const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl)); | |
2154 | |
2155 if (streq (name, ".zdata") || streq (name, ".zbss")) | |
2156 v850_set_data_area (decl, DATA_AREA_ZDA); | |
2157 | |
2158 else if (streq (name, ".sdata") || streq (name, ".sbss")) | |
2159 v850_set_data_area (decl, DATA_AREA_SDA); | |
2160 | |
2161 else if (streq (name, ".tdata")) | |
2162 v850_set_data_area (decl, DATA_AREA_TDA); | |
2163 } | |
2164 | |
2165 /* If no attribute, support -m{zda,sda,tda}=n */ | |
2166 else | |
2167 { | |
2168 int size = int_size_in_bytes (TREE_TYPE (decl)); | |
2169 if (size <= 0) | |
2170 ; | |
2171 | |
2172 else if (size <= small_memory [(int) SMALL_MEMORY_TDA].max) | |
2173 v850_set_data_area (decl, DATA_AREA_TDA); | |
2174 | |
2175 else if (size <= small_memory [(int) SMALL_MEMORY_SDA].max) | |
2176 v850_set_data_area (decl, DATA_AREA_SDA); | |
2177 | |
2178 else if (size <= small_memory [(int) SMALL_MEMORY_ZDA].max) | |
2179 v850_set_data_area (decl, DATA_AREA_ZDA); | |
2180 } | |
2181 | |
2182 if (v850_get_data_area (decl) == DATA_AREA_NORMAL) | |
2183 return; | |
2184 } | |
2185 | |
2186 flags = SYMBOL_REF_FLAGS (symbol); | |
2187 switch (v850_get_data_area (decl)) | |
2188 { | |
2189 case DATA_AREA_ZDA: flags |= SYMBOL_FLAG_ZDA; break; | |
2190 case DATA_AREA_TDA: flags |= SYMBOL_FLAG_TDA; break; | |
2191 case DATA_AREA_SDA: flags |= SYMBOL_FLAG_SDA; break; | |
2192 default: gcc_unreachable (); | |
2193 } | |
2194 SYMBOL_REF_FLAGS (symbol) = flags; | |
2195 } | |
2196 | |
2197 static void | |
2198 v850_encode_section_info (tree decl, rtx rtl, int first) | |
2199 { | |
2200 default_encode_section_info (decl, rtl, first); | |
2201 | |
2202 if (TREE_CODE (decl) == VAR_DECL | |
2203 && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) | |
2204 v850_encode_data_area (decl, XEXP (rtl, 0)); | |
2205 } | |
2206 | |
2207 /* Construct a JR instruction to a routine that will perform the equivalent of | |
2208 the RTL passed in as an argument. This RTL is a function epilogue that | |
2209 pops registers off the stack and possibly releases some extra stack space | |
2210 as well. The code has already verified that the RTL matches these | |
2211 requirements. */ | |
2212 char * | |
2213 construct_restore_jr (rtx op) | |
2214 { | |
2215 int count = XVECLEN (op, 0); | |
2216 int stack_bytes; | |
2217 unsigned long int mask; | |
2218 unsigned long int first; | |
2219 unsigned long int last; | |
2220 int i; | |
2221 static char buff [100]; /* XXX */ | |
2222 | |
2223 if (count <= 2) | |
2224 { | |
2225 error ("bogus JR construction: %d", count); | |
2226 return NULL; | |
2227 } | |
2228 | |
2229 /* Work out how many bytes to pop off the stack before retrieving | |
2230 registers. */ | |
2231 gcc_assert (GET_CODE (XVECEXP (op, 0, 1)) == SET); | |
2232 gcc_assert (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS); | |
2233 gcc_assert (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)) == CONST_INT); | |
2234 | |
2235 stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)); | |
2236 | |
2237 /* Each pop will remove 4 bytes from the stack.... */ | |
2238 stack_bytes -= (count - 2) * 4; | |
2239 | |
2240 /* Make sure that the amount we are popping either 0 or 16 bytes. */ | |
2241 if (stack_bytes != 0 && stack_bytes != 16) | |
2242 { | |
2243 error ("bad amount of stack space removal: %d", stack_bytes); | |
2244 return NULL; | |
2245 } | |
2246 | |
2247 /* Now compute the bit mask of registers to push. */ | |
2248 mask = 0; | |
2249 for (i = 2; i < count; i++) | |
2250 { | |
2251 rtx vector_element = XVECEXP (op, 0, i); | |
2252 | |
2253 gcc_assert (GET_CODE (vector_element) == SET); | |
2254 gcc_assert (GET_CODE (SET_DEST (vector_element)) == REG); | |
2255 gcc_assert (register_is_ok_for_epilogue (SET_DEST (vector_element), | |
2256 SImode)); | |
2257 | |
2258 mask |= 1 << REGNO (SET_DEST (vector_element)); | |
2259 } | |
2260 | |
2261 /* Scan for the first register to pop. */ | |
2262 for (first = 0; first < 32; first++) | |
2263 { | |
2264 if (mask & (1 << first)) | |
2265 break; | |
2266 } | |
2267 | |
2268 gcc_assert (first < 32); | |
2269 | |
2270 /* Discover the last register to pop. */ | |
2271 if (mask & (1 << LINK_POINTER_REGNUM)) | |
2272 { | |
2273 gcc_assert (stack_bytes == 16); | |
2274 | |
2275 last = LINK_POINTER_REGNUM; | |
2276 } | |
2277 else | |
2278 { | |
2279 gcc_assert (!stack_bytes); | |
2280 gcc_assert (mask & (1 << 29)); | |
2281 | |
2282 last = 29; | |
2283 } | |
2284 | |
2285 /* Note, it is possible to have gaps in the register mask. | |
2286 We ignore this here, and generate a JR anyway. We will | |
2287 be popping more registers than is strictly necessary, but | |
2288 it does save code space. */ | |
2289 | |
2290 if (TARGET_LONG_CALLS) | |
2291 { | |
2292 char name[40]; | |
2293 | |
2294 if (first == last) | |
2295 sprintf (name, "__return_%s", reg_names [first]); | |
2296 else | |
2297 sprintf (name, "__return_%s_%s", reg_names [first], reg_names [last]); | |
2298 | |
2299 sprintf (buff, "movhi hi(%s), r0, r6\n\tmovea lo(%s), r6, r6\n\tjmp r6", | |
2300 name, name); | |
2301 } | |
2302 else | |
2303 { | |
2304 if (first == last) | |
2305 sprintf (buff, "jr __return_%s", reg_names [first]); | |
2306 else | |
2307 sprintf (buff, "jr __return_%s_%s", reg_names [first], reg_names [last]); | |
2308 } | |
2309 | |
2310 return buff; | |
2311 } | |
2312 | |
2313 | |
2314 /* Construct a JARL instruction to a routine that will perform the equivalent | |
2315 of the RTL passed as a parameter. This RTL is a function prologue that | |
2316 saves some of the registers r20 - r31 onto the stack, and possibly acquires | |
2317 some stack space as well. The code has already verified that the RTL | |
2318 matches these requirements. */ | |
2319 char * | |
2320 construct_save_jarl (rtx op) | |
2321 { | |
2322 int count = XVECLEN (op, 0); | |
2323 int stack_bytes; | |
2324 unsigned long int mask; | |
2325 unsigned long int first; | |
2326 unsigned long int last; | |
2327 int i; | |
2328 static char buff [100]; /* XXX */ | |
2329 | |
2330 if (count <= 2) | |
2331 { | |
2332 error ("bogus JARL construction: %d\n", count); | |
2333 return NULL; | |
2334 } | |
2335 | |
2336 /* Paranoia. */ | |
2337 gcc_assert (GET_CODE (XVECEXP (op, 0, 0)) == SET); | |
2338 gcc_assert (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) == PLUS); | |
2339 gcc_assert (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0)) == REG); | |
2340 gcc_assert (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)) == CONST_INT); | |
2341 | |
2342 /* Work out how many bytes to push onto the stack after storing the | |
2343 registers. */ | |
2344 stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)); | |
2345 | |
2346 /* Each push will put 4 bytes from the stack.... */ | |
2347 stack_bytes += (count - (TARGET_LONG_CALLS ? 3 : 2)) * 4; | |
2348 | |
2349 /* Make sure that the amount we are popping either 0 or 16 bytes. */ | |
2350 if (stack_bytes != 0 && stack_bytes != -16) | |
2351 { | |
2352 error ("bad amount of stack space removal: %d", stack_bytes); | |
2353 return NULL; | |
2354 } | |
2355 | |
2356 /* Now compute the bit mask of registers to push. */ | |
2357 mask = 0; | |
2358 for (i = 1; i < count - (TARGET_LONG_CALLS ? 2 : 1); i++) | |
2359 { | |
2360 rtx vector_element = XVECEXP (op, 0, i); | |
2361 | |
2362 gcc_assert (GET_CODE (vector_element) == SET); | |
2363 gcc_assert (GET_CODE (SET_SRC (vector_element)) == REG); | |
2364 gcc_assert (register_is_ok_for_epilogue (SET_SRC (vector_element), | |
2365 SImode)); | |
2366 | |
2367 mask |= 1 << REGNO (SET_SRC (vector_element)); | |
2368 } | |
2369 | |
2370 /* Scan for the first register to push. */ | |
2371 for (first = 0; first < 32; first++) | |
2372 { | |
2373 if (mask & (1 << first)) | |
2374 break; | |
2375 } | |
2376 | |
2377 gcc_assert (first < 32); | |
2378 | |
2379 /* Discover the last register to push. */ | |
2380 if (mask & (1 << LINK_POINTER_REGNUM)) | |
2381 { | |
2382 gcc_assert (stack_bytes == -16); | |
2383 | |
2384 last = LINK_POINTER_REGNUM; | |
2385 } | |
2386 else | |
2387 { | |
2388 gcc_assert (!stack_bytes); | |
2389 gcc_assert (mask & (1 << 29)); | |
2390 | |
2391 last = 29; | |
2392 } | |
2393 | |
2394 /* Note, it is possible to have gaps in the register mask. | |
2395 We ignore this here, and generate a JARL anyway. We will | |
2396 be pushing more registers than is strictly necessary, but | |
2397 it does save code space. */ | |
2398 | |
2399 if (TARGET_LONG_CALLS) | |
2400 { | |
2401 char name[40]; | |
2402 | |
2403 if (first == last) | |
2404 sprintf (name, "__save_%s", reg_names [first]); | |
2405 else | |
2406 sprintf (name, "__save_%s_%s", reg_names [first], reg_names [last]); | |
2407 | |
2408 sprintf (buff, "movhi hi(%s), r0, r11\n\tmovea lo(%s), r11, r11\n\tjarl .+4, r10\n\tadd 4, r10\n\tjmp r11", | |
2409 name, name); | |
2410 } | |
2411 else | |
2412 { | |
2413 if (first == last) | |
2414 sprintf (buff, "jarl __save_%s, r10", reg_names [first]); | |
2415 else | |
2416 sprintf (buff, "jarl __save_%s_%s, r10", reg_names [first], | |
2417 reg_names [last]); | |
2418 } | |
2419 | |
2420 return buff; | |
2421 } | |
2422 | |
2423 extern tree last_assemble_variable_decl; | |
2424 extern int size_directive_output; | |
2425 | |
2426 /* A version of asm_output_aligned_bss() that copes with the special | |
2427 data areas of the v850. */ | |
2428 void | |
2429 v850_output_aligned_bss (FILE * file, | |
2430 tree decl, | |
2431 const char * name, | |
2432 unsigned HOST_WIDE_INT size, | |
2433 int align) | |
2434 { | |
2435 switch (v850_get_data_area (decl)) | |
2436 { | |
2437 case DATA_AREA_ZDA: | |
2438 switch_to_section (zbss_section); | |
2439 break; | |
2440 | |
2441 case DATA_AREA_SDA: | |
2442 switch_to_section (sbss_section); | |
2443 break; | |
2444 | |
2445 case DATA_AREA_TDA: | |
2446 switch_to_section (tdata_section); | |
2447 | |
2448 default: | |
2449 switch_to_section (bss_section); | |
2450 break; | |
2451 } | |
2452 | |
2453 ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT)); | |
2454 #ifdef ASM_DECLARE_OBJECT_NAME | |
2455 last_assemble_variable_decl = decl; | |
2456 ASM_DECLARE_OBJECT_NAME (file, name, decl); | |
2457 #else | |
2458 /* Standard thing is just output label for the object. */ | |
2459 ASM_OUTPUT_LABEL (file, name); | |
2460 #endif /* ASM_DECLARE_OBJECT_NAME */ | |
2461 ASM_OUTPUT_SKIP (file, size ? size : 1); | |
2462 } | |
2463 | |
2464 /* Called via the macro ASM_OUTPUT_DECL_COMMON */ | |
2465 void | |
2466 v850_output_common (FILE * file, | |
2467 tree decl, | |
2468 const char * name, | |
2469 int size, | |
2470 int align) | |
2471 { | |
2472 if (decl == NULL_TREE) | |
2473 { | |
2474 fprintf (file, "%s", COMMON_ASM_OP); | |
2475 } | |
2476 else | |
2477 { | |
2478 switch (v850_get_data_area (decl)) | |
2479 { | |
2480 case DATA_AREA_ZDA: | |
2481 fprintf (file, "%s", ZCOMMON_ASM_OP); | |
2482 break; | |
2483 | |
2484 case DATA_AREA_SDA: | |
2485 fprintf (file, "%s", SCOMMON_ASM_OP); | |
2486 break; | |
2487 | |
2488 case DATA_AREA_TDA: | |
2489 fprintf (file, "%s", TCOMMON_ASM_OP); | |
2490 break; | |
2491 | |
2492 default: | |
2493 fprintf (file, "%s", COMMON_ASM_OP); | |
2494 break; | |
2495 } | |
2496 } | |
2497 | |
2498 assemble_name (file, name); | |
2499 fprintf (file, ",%u,%u\n", size, align / BITS_PER_UNIT); | |
2500 } | |
2501 | |
2502 /* Called via the macro ASM_OUTPUT_DECL_LOCAL */ | |
2503 void | |
2504 v850_output_local (FILE * file, | |
2505 tree decl, | |
2506 const char * name, | |
2507 int size, | |
2508 int align) | |
2509 { | |
2510 fprintf (file, "%s", LOCAL_ASM_OP); | |
2511 assemble_name (file, name); | |
2512 fprintf (file, "\n"); | |
2513 | |
2514 ASM_OUTPUT_ALIGNED_DECL_COMMON (file, decl, name, size, align); | |
2515 } | |
2516 | |
2517 /* Add data area to the given declaration if a ghs data area pragma is | |
2518 currently in effect (#pragma ghs startXXX/endXXX). */ | |
2519 static void | |
2520 v850_insert_attributes (tree decl, tree * attr_ptr ATTRIBUTE_UNUSED ) | |
2521 { | |
2522 if (data_area_stack | |
2523 && data_area_stack->data_area | |
2524 && current_function_decl == NULL_TREE | |
2525 && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == CONST_DECL) | |
2526 && v850_get_data_area (decl) == DATA_AREA_NORMAL) | |
2527 v850_set_data_area (decl, data_area_stack->data_area); | |
2528 | |
2529 /* Initialize the default names of the v850 specific sections, | |
2530 if this has not been done before. */ | |
2531 | |
2532 if (GHS_default_section_names [(int) GHS_SECTION_KIND_SDATA] == NULL) | |
2533 { | |
2534 GHS_default_section_names [(int) GHS_SECTION_KIND_SDATA] | |
2535 = build_string (sizeof (".sdata")-1, ".sdata"); | |
2536 | |
2537 GHS_default_section_names [(int) GHS_SECTION_KIND_ROSDATA] | |
2538 = build_string (sizeof (".rosdata")-1, ".rosdata"); | |
2539 | |
2540 GHS_default_section_names [(int) GHS_SECTION_KIND_TDATA] | |
2541 = build_string (sizeof (".tdata")-1, ".tdata"); | |
2542 | |
2543 GHS_default_section_names [(int) GHS_SECTION_KIND_ZDATA] | |
2544 = build_string (sizeof (".zdata")-1, ".zdata"); | |
2545 | |
2546 GHS_default_section_names [(int) GHS_SECTION_KIND_ROZDATA] | |
2547 = build_string (sizeof (".rozdata")-1, ".rozdata"); | |
2548 } | |
2549 | |
2550 if (current_function_decl == NULL_TREE | |
2551 && (TREE_CODE (decl) == VAR_DECL | |
2552 || TREE_CODE (decl) == CONST_DECL | |
2553 || TREE_CODE (decl) == FUNCTION_DECL) | |
2554 && (!DECL_EXTERNAL (decl) || DECL_INITIAL (decl)) | |
2555 && !DECL_SECTION_NAME (decl)) | |
2556 { | |
2557 enum GHS_section_kind kind = GHS_SECTION_KIND_DEFAULT; | |
2558 tree chosen_section; | |
2559 | |
2560 if (TREE_CODE (decl) == FUNCTION_DECL) | |
2561 kind = GHS_SECTION_KIND_TEXT; | |
2562 else | |
2563 { | |
2564 /* First choose a section kind based on the data area of the decl. */ | |
2565 switch (v850_get_data_area (decl)) | |
2566 { | |
2567 default: | |
2568 gcc_unreachable (); | |
2569 | |
2570 case DATA_AREA_SDA: | |
2571 kind = ((TREE_READONLY (decl)) | |
2572 ? GHS_SECTION_KIND_ROSDATA | |
2573 : GHS_SECTION_KIND_SDATA); | |
2574 break; | |
2575 | |
2576 case DATA_AREA_TDA: | |
2577 kind = GHS_SECTION_KIND_TDATA; | |
2578 break; | |
2579 | |
2580 case DATA_AREA_ZDA: | |
2581 kind = ((TREE_READONLY (decl)) | |
2582 ? GHS_SECTION_KIND_ROZDATA | |
2583 : GHS_SECTION_KIND_ZDATA); | |
2584 break; | |
2585 | |
2586 case DATA_AREA_NORMAL: /* default data area */ | |
2587 if (TREE_READONLY (decl)) | |
2588 kind = GHS_SECTION_KIND_RODATA; | |
2589 else if (DECL_INITIAL (decl)) | |
2590 kind = GHS_SECTION_KIND_DATA; | |
2591 else | |
2592 kind = GHS_SECTION_KIND_BSS; | |
2593 } | |
2594 } | |
2595 | |
2596 /* Now, if the section kind has been explicitly renamed, | |
2597 then attach a section attribute. */ | |
2598 chosen_section = GHS_current_section_names [(int) kind]; | |
2599 | |
2600 /* Otherwise, if this kind of section needs an explicit section | |
2601 attribute, then also attach one. */ | |
2602 if (chosen_section == NULL) | |
2603 chosen_section = GHS_default_section_names [(int) kind]; | |
2604 | |
2605 if (chosen_section) | |
2606 { | |
2607 /* Only set the section name if specified by a pragma, because | |
2608 otherwise it will force those variables to get allocated storage | |
2609 in this module, rather than by the linker. */ | |
2610 DECL_SECTION_NAME (decl) = chosen_section; | |
2611 } | |
2612 } | |
2613 } | |
2614 | |
2615 /* Construct a DISPOSE instruction that is the equivalent of | |
2616 the given RTX. We have already verified that this should | |
2617 be possible. */ | |
2618 | |
2619 char * | |
2620 construct_dispose_instruction (rtx op) | |
2621 { | |
2622 int count = XVECLEN (op, 0); | |
2623 int stack_bytes; | |
2624 unsigned long int mask; | |
2625 int i; | |
2626 static char buff[ 100 ]; /* XXX */ | |
2627 int use_callt = 0; | |
2628 | |
2629 if (count <= 2) | |
2630 { | |
2631 error ("bogus DISPOSE construction: %d", count); | |
2632 return NULL; | |
2633 } | |
2634 | |
2635 /* Work out how many bytes to pop off the | |
2636 stack before retrieving registers. */ | |
2637 gcc_assert (GET_CODE (XVECEXP (op, 0, 1)) == SET); | |
2638 gcc_assert (GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS); | |
2639 gcc_assert (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)) == CONST_INT); | |
2640 | |
2641 stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1)); | |
2642 | |
2643 /* Each pop will remove 4 bytes from the stack.... */ | |
2644 stack_bytes -= (count - 2) * 4; | |
2645 | |
2646 /* Make sure that the amount we are popping | |
2647 will fit into the DISPOSE instruction. */ | |
2648 if (stack_bytes > 128) | |
2649 { | |
2650 error ("too much stack space to dispose of: %d", stack_bytes); | |
2651 return NULL; | |
2652 } | |
2653 | |
2654 /* Now compute the bit mask of registers to push. */ | |
2655 mask = 0; | |
2656 | |
2657 for (i = 2; i < count; i++) | |
2658 { | |
2659 rtx vector_element = XVECEXP (op, 0, i); | |
2660 | |
2661 gcc_assert (GET_CODE (vector_element) == SET); | |
2662 gcc_assert (GET_CODE (SET_DEST (vector_element)) == REG); | |
2663 gcc_assert (register_is_ok_for_epilogue (SET_DEST (vector_element), | |
2664 SImode)); | |
2665 | |
2666 if (REGNO (SET_DEST (vector_element)) == 2) | |
2667 use_callt = 1; | |
2668 else | |
2669 mask |= 1 << REGNO (SET_DEST (vector_element)); | |
2670 } | |
2671 | |
2672 if (! TARGET_DISABLE_CALLT | |
2673 && (use_callt || stack_bytes == 0 || stack_bytes == 16)) | |
2674 { | |
2675 if (use_callt) | |
2676 { | |
2677 sprintf (buff, "callt ctoff(__callt_return_r2_r%d)", (mask & (1 << 31)) ? 31 : 29); | |
2678 return buff; | |
2679 } | |
2680 else | |
2681 { | |
2682 for (i = 20; i < 32; i++) | |
2683 if (mask & (1 << i)) | |
2684 break; | |
2685 | |
2686 if (i == 31) | |
2687 sprintf (buff, "callt ctoff(__callt_return_r31c)"); | |
2688 else | |
2689 sprintf (buff, "callt ctoff(__callt_return_r%d_r%d%s)", | |
2690 i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : ""); | |
2691 } | |
2692 } | |
2693 else | |
2694 { | |
2695 static char regs [100]; /* XXX */ | |
2696 int done_one; | |
2697 | |
2698 /* Generate the DISPOSE instruction. Note we could just issue the | |
2699 bit mask as a number as the assembler can cope with this, but for | |
2700 the sake of our readers we turn it into a textual description. */ | |
2701 regs[0] = 0; | |
2702 done_one = 0; | |
2703 | |
2704 for (i = 20; i < 32; i++) | |
2705 { | |
2706 if (mask & (1 << i)) | |
2707 { | |
2708 int first; | |
2709 | |
2710 if (done_one) | |
2711 strcat (regs, ", "); | |
2712 else | |
2713 done_one = 1; | |
2714 | |
2715 first = i; | |
2716 strcat (regs, reg_names[ first ]); | |
2717 | |
2718 for (i++; i < 32; i++) | |
2719 if ((mask & (1 << i)) == 0) | |
2720 break; | |
2721 | |
2722 if (i > first + 1) | |
2723 { | |
2724 strcat (regs, " - "); | |
2725 strcat (regs, reg_names[ i - 1 ] ); | |
2726 } | |
2727 } | |
2728 } | |
2729 | |
2730 sprintf (buff, "dispose %d {%s}, r31", stack_bytes / 4, regs); | |
2731 } | |
2732 | |
2733 return buff; | |
2734 } | |
2735 | |
2736 /* Construct a PREPARE instruction that is the equivalent of | |
2737 the given RTL. We have already verified that this should | |
2738 be possible. */ | |
2739 | |
2740 char * | |
2741 construct_prepare_instruction (rtx op) | |
2742 { | |
2743 int count = XVECLEN (op, 0); | |
2744 int stack_bytes; | |
2745 unsigned long int mask; | |
2746 int i; | |
2747 static char buff[ 100 ]; /* XXX */ | |
2748 int use_callt = 0; | |
2749 | |
2750 if (count <= 1) | |
2751 { | |
2752 error ("bogus PREPEARE construction: %d", count); | |
2753 return NULL; | |
2754 } | |
2755 | |
2756 /* Work out how many bytes to push onto | |
2757 the stack after storing the registers. */ | |
2758 gcc_assert (GET_CODE (XVECEXP (op, 0, 0)) == SET); | |
2759 gcc_assert (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) == PLUS); | |
2760 gcc_assert (GET_CODE (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)) == CONST_INT); | |
2761 | |
2762 stack_bytes = INTVAL (XEXP (SET_SRC (XVECEXP (op, 0, 0)), 1)); | |
2763 | |
2764 /* Each push will put 4 bytes from the stack. */ | |
2765 stack_bytes += (count - 1) * 4; | |
2766 | |
2767 /* Make sure that the amount we are popping | |
2768 will fit into the DISPOSE instruction. */ | |
2769 if (stack_bytes < -128) | |
2770 { | |
2771 error ("too much stack space to prepare: %d", stack_bytes); | |
2772 return NULL; | |
2773 } | |
2774 | |
2775 /* Now compute the bit mask of registers to push. */ | |
2776 mask = 0; | |
2777 for (i = 1; i < count; i++) | |
2778 { | |
2779 rtx vector_element = XVECEXP (op, 0, i); | |
2780 | |
2781 gcc_assert (GET_CODE (vector_element) == SET); | |
2782 gcc_assert (GET_CODE (SET_SRC (vector_element)) == REG); | |
2783 gcc_assert (register_is_ok_for_epilogue (SET_SRC (vector_element), | |
2784 SImode)); | |
2785 | |
2786 if (REGNO (SET_SRC (vector_element)) == 2) | |
2787 use_callt = 1; | |
2788 else | |
2789 mask |= 1 << REGNO (SET_SRC (vector_element)); | |
2790 } | |
2791 | |
2792 if ((! TARGET_DISABLE_CALLT) | |
2793 && (use_callt || stack_bytes == 0 || stack_bytes == -16)) | |
2794 { | |
2795 if (use_callt) | |
2796 { | |
2797 sprintf (buff, "callt ctoff(__callt_save_r2_r%d)", (mask & (1 << 31)) ? 31 : 29 ); | |
2798 return buff; | |
2799 } | |
2800 | |
2801 for (i = 20; i < 32; i++) | |
2802 if (mask & (1 << i)) | |
2803 break; | |
2804 | |
2805 if (i == 31) | |
2806 sprintf (buff, "callt ctoff(__callt_save_r31c)"); | |
2807 else | |
2808 sprintf (buff, "callt ctoff(__callt_save_r%d_r%d%s)", | |
2809 i, (mask & (1 << 31)) ? 31 : 29, stack_bytes ? "c" : ""); | |
2810 } | |
2811 else | |
2812 { | |
2813 static char regs [100]; /* XXX */ | |
2814 int done_one; | |
2815 | |
2816 | |
2817 /* Generate the PREPARE instruction. Note we could just issue the | |
2818 bit mask as a number as the assembler can cope with this, but for | |
2819 the sake of our readers we turn it into a textual description. */ | |
2820 regs[0] = 0; | |
2821 done_one = 0; | |
2822 | |
2823 for (i = 20; i < 32; i++) | |
2824 { | |
2825 if (mask & (1 << i)) | |
2826 { | |
2827 int first; | |
2828 | |
2829 if (done_one) | |
2830 strcat (regs, ", "); | |
2831 else | |
2832 done_one = 1; | |
2833 | |
2834 first = i; | |
2835 strcat (regs, reg_names[ first ]); | |
2836 | |
2837 for (i++; i < 32; i++) | |
2838 if ((mask & (1 << i)) == 0) | |
2839 break; | |
2840 | |
2841 if (i > first + 1) | |
2842 { | |
2843 strcat (regs, " - "); | |
2844 strcat (regs, reg_names[ i - 1 ] ); | |
2845 } | |
2846 } | |
2847 } | |
2848 | |
2849 sprintf (buff, "prepare {%s}, %d", regs, (- stack_bytes) / 4); | |
2850 } | |
2851 | |
2852 return buff; | |
2853 } | |
2854 | |
2855 /* Return an RTX indicating where the return address to the | |
2856 calling function can be found. */ | |
2857 | |
2858 rtx | |
2859 v850_return_addr (int count) | |
2860 { | |
2861 if (count != 0) | |
2862 return const0_rtx; | |
2863 | |
2864 return get_hard_reg_initial_val (Pmode, LINK_POINTER_REGNUM); | |
2865 } | |
2866 | |
2867 /* Implement TARGET_ASM_INIT_SECTIONS. */ | |
2868 | |
2869 static void | |
2870 v850_asm_init_sections (void) | |
2871 { | |
2872 rosdata_section | |
2873 = get_unnamed_section (0, output_section_asm_op, | |
2874 "\t.section .rosdata,\"a\""); | |
2875 | |
2876 rozdata_section | |
2877 = get_unnamed_section (0, output_section_asm_op, | |
2878 "\t.section .rozdata,\"a\""); | |
2879 | |
2880 tdata_section | |
2881 = get_unnamed_section (SECTION_WRITE, output_section_asm_op, | |
2882 "\t.section .tdata,\"aw\""); | |
2883 | |
2884 zdata_section | |
2885 = get_unnamed_section (SECTION_WRITE, output_section_asm_op, | |
2886 "\t.section .zdata,\"aw\""); | |
2887 | |
2888 zbss_section | |
2889 = get_unnamed_section (SECTION_WRITE | SECTION_BSS, | |
2890 output_section_asm_op, | |
2891 "\t.section .zbss,\"aw\""); | |
2892 } | |
2893 | |
2894 static section * | |
2895 v850_select_section (tree exp, | |
2896 int reloc ATTRIBUTE_UNUSED, | |
2897 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED) | |
2898 { | |
2899 if (TREE_CODE (exp) == VAR_DECL) | |
2900 { | |
2901 int is_const; | |
2902 if (!TREE_READONLY (exp) | |
2903 || TREE_SIDE_EFFECTS (exp) | |
2904 || !DECL_INITIAL (exp) | |
2905 || (DECL_INITIAL (exp) != error_mark_node | |
2906 && !TREE_CONSTANT (DECL_INITIAL (exp)))) | |
2907 is_const = FALSE; | |
2908 else | |
2909 is_const = TRUE; | |
2910 | |
2911 switch (v850_get_data_area (exp)) | |
2912 { | |
2913 case DATA_AREA_ZDA: | |
2914 return is_const ? rozdata_section : zdata_section; | |
2915 | |
2916 case DATA_AREA_TDA: | |
2917 return tdata_section; | |
2918 | |
2919 case DATA_AREA_SDA: | |
2920 return is_const ? rosdata_section : sdata_section; | |
2921 | |
2922 default: | |
2923 return is_const ? readonly_data_section : data_section; | |
2924 } | |
2925 } | |
2926 return readonly_data_section; | |
2927 } | |
2928 | |
2929 /* Worker function for TARGET_RETURN_IN_MEMORY. */ | |
2930 | |
2931 static bool | |
2932 v850_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) | |
2933 { | |
2934 /* Return values > 8 bytes in length in memory. */ | |
2935 return int_size_in_bytes (type) > 8 || TYPE_MODE (type) == BLKmode; | |
2936 } | |
2937 | |
2938 /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */ | |
2939 | |
2940 static void | |
2941 v850_setup_incoming_varargs (CUMULATIVE_ARGS *ca, | |
2942 enum machine_mode mode ATTRIBUTE_UNUSED, | |
2943 tree type ATTRIBUTE_UNUSED, | |
2944 int *pretend_arg_size ATTRIBUTE_UNUSED, | |
2945 int second_time ATTRIBUTE_UNUSED) | |
2946 { | |
2947 ca->anonymous_args = (!TARGET_GHS ? 1 : 0); | |
2948 } | |
2949 | |
2950 #include "gt-v850.h" |