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