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