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