]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/cris/cris.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / config / cris / cris.cc
CommitLineData
0b85d816 1/* Definitions for GCC. Part of the machine description for CRIS.
83ffe9cd 2 Copyright (C) 1998-2023 Free Software Foundation, Inc.
0b85d816
HPN
3 Contributed by Axis Communications. Written by Hans-Peter Nilsson.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
2f83c7d6 9the Free Software Foundation; either version 3, or (at your option)
0b85d816
HPN
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
2f83c7d6
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
0b85d816 20
8fcc61f8
RS
21#define IN_TARGET_CODE 1
22
0b85d816
HPN
23#include "config.h"
24#include "system.h"
4977bab6 25#include "coretypes.h"
c7131fb2 26#include "backend.h"
e11c4407 27#include "target.h"
0b85d816 28#include "rtl.h"
e11c4407 29#include "tree.h"
314e6352
ML
30#include "stringpool.h"
31#include "attribs.h"
e11c4407 32#include "cfghooks.h"
c7131fb2 33#include "df.h"
4d0cdd0c 34#include "memmodel.h"
e11c4407
AM
35#include "tm_p.h"
36#include "optabs.h"
0b85d816 37#include "regs.h"
e11c4407
AM
38#include "emit-rtl.h"
39#include "recog.h"
40#include "cgraph.h"
41#include "diagnostic-core.h"
0b85d816 42#include "conditions.h"
0b85d816 43#include "insn-attr.h"
40e23961 44#include "alias.h"
d8a2d370
DN
45#include "varasm.h"
46#include "stor-layout.h"
47#include "calls.h"
36566b39 48#include "explow.h"
0b85d816 49#include "expr.h"
15883505 50#include "reload.h"
78b14aa6 51#include "output.h"
06cadf63 52#include "tm-constrs.h"
9b2b7279 53#include "builtins.h"
9a2ae08b
HPN
54#include "cfgrtl.h"
55#include "tree-pass.h"
0b85d816 56
994c5d85 57/* This file should be included last. */
d58627a0
RS
58#include "target-def.h"
59
0b85d816
HPN
60/* Usable when we have an amount to add or subtract, and want the
61 optimal size of the insn. */
62#define ADDITIVE_SIZE_MODIFIER(size) \
63 ((size) <= 63 ? "q" : (size) <= 255 ? "u.b" : (size) <= 65535 ? "u.w" : ".d")
64
a52453cc 65#define LOSE_AND_RETURN(msgid, x) \
3d556836
HPN
66 do \
67 { \
a52453cc 68 cris_operand_lossage (msgid, x); \
3d556836
HPN
69 return; \
70 } while (0)
71
04539954
HPN
72enum cris_retinsn_type
73 { CRIS_RETINSN_UNKNOWN = 0, CRIS_RETINSN_RET, CRIS_RETINSN_JUMP };
74
0b85d816 75/* Per-function machine data. */
d1b38208 76struct GTY(()) machine_function
0b85d816
HPN
77 {
78 int needs_return_address_on_stack;
d29b4b1b
HPN
79
80 /* This is the number of registers we save in the prologue due to
81 stdarg. */
82 int stdarg_regs;
83
04539954 84 enum cris_retinsn_type return_type;
0b85d816
HPN
85 };
86
0b85d816
HPN
87/* This little fix suppresses the 'u' or 's' when '%e' in assembly
88 pattern. */
89static char cris_output_insn_is_bound = 0;
90
453bd0f5
HPN
91/* In code for output macros, this is how we know whether e.g. constant
92 goes in code or in a static initializer. */
93static int in_code = 0;
94
ef4bddc2 95static machine_mode cris_promote_function_mode (const_tree, machine_mode,
cde0f3fd
PB
96 int *, const_tree, int);
97
ef4bddc2 98static unsigned int cris_atomic_align_for_mode (machine_mode);
faee0106 99
6640377c 100static void cris_print_base (rtx, FILE *);
0b85d816 101
6640377c 102static void cris_print_index (rtx, FILE *);
0b85d816 103
453bd0f5
HPN
104static void cris_output_addr_const (FILE *, rtx);
105
6640377c 106static struct machine_function * cris_init_machine_status (void);
0b85d816 107
a2fef3a4
KH
108static rtx cris_struct_value_rtx (tree, int);
109
e7056ca4
RS
110static void cris_setup_incoming_varargs (cumulative_args_t,
111 const function_arg_info &,
112 int *, int);
558d352a 113
6640377c 114static int cris_initial_frame_pointer_offset (void);
3d556836 115
6640377c 116static void cris_operand_lossage (const char *, rtx);
3d556836 117
d0780379 118static int cris_reg_saved_in_regsave_area (unsigned int);
04539954 119
ed5c4a10
NF
120static void cris_print_operand (FILE *, rtx, int);
121
cc8ca59e 122static void cris_print_operand_address (FILE *, machine_mode, rtx);
ed5c4a10
NF
123
124static bool cris_print_operand_punct_valid_p (unsigned char code);
125
5efd84c5
NF
126static void cris_conditional_register_usage (void);
127
c590b625 128static void cris_asm_output_mi_thunk
6640377c 129 (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
c590b625 130
6640377c 131static void cris_file_start (void);
c15c90bb 132static void cris_init_libfuncs (void);
1bc7c5b6 133
9a2ae08b
HPN
134static unsigned int cris_postdbr_cmpelim (void);
135
45dbdfd4
AS
136static reg_class_t cris_preferred_reload_class (rtx, reg_class_t);
137
ef4bddc2
RS
138static int cris_register_move_cost (machine_mode, reg_class_t, reg_class_t);
139static int cris_memory_move_cost (machine_mode, reg_class_t, bool);
b3e01c3d 140static machine_mode cris_cc_modes_compatible (machine_mode, machine_mode);
e548c9df 141static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool);
ef4bddc2 142static int cris_address_cost (rtx, machine_mode, addr_space_t, bool);
52090e4d
RS
143static bool cris_pass_by_reference (cumulative_args_t,
144 const function_arg_info &);
a7c81bc1
RS
145static int cris_arg_partial_bytes (cumulative_args_t,
146 const function_arg_info &);
6783fdb7 147static rtx cris_function_arg (cumulative_args_t, const function_arg_info &);
d5cc9181 148static rtx cris_function_incoming_arg (cumulative_args_t,
6783fdb7 149 const function_arg_info &);
6930c98c
RS
150static void cris_function_arg_advance (cumulative_args_t,
151 const function_arg_info &);
7ca35180 152static rtx_insn *cris_md_asm_adjust (vec<rtx> &, vec<rtx> &,
e52ef6e6 153 vec<machine_mode> &, vec<const char *> &,
8d76ff99 154 vec<rtx> &, HARD_REG_SET &, location_t);
c590b625 155
c5387660 156static void cris_option_override (void);
2a186d97 157
b52b1749
AS
158static bool cris_frame_pointer_required (void);
159
3e322b77
RH
160static void cris_asm_trampoline_template (FILE *);
161static void cris_trampoline_init (rtx, tree, rtx);
162
4d696ad0 163static rtx cris_function_value(const_tree, const_tree, bool);
ef4bddc2 164static rtx cris_libcall_value (machine_mode, const_rtx);
2283c416 165static bool cris_function_value_regno_p (const unsigned int);
c43f4279 166static unsigned int cris_hard_regno_nregs (unsigned int, machine_mode);
f939c3e6 167static bool cris_hard_regno_mode_ok (unsigned int, machine_mode);
f073de07 168static HOST_WIDE_INT cris_static_rtx_alignment (machine_mode);
58e17cf8 169static HOST_WIDE_INT cris_constant_alignment (const_tree, HOST_WIDE_INT);
4d696ad0 170
0b85d816
HPN
171/* This is the parsed result of the "-max-stack-stackframe=" option. If
172 it (still) is zero, then there was no such option given. */
173int cris_max_stackframe = 0;
174
175/* This is the parsed result of the "-march=" option, if given. */
176int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
177
301d03af
RS
178#undef TARGET_ASM_ALIGNED_HI_OP
179#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
180#undef TARGET_ASM_ALIGNED_SI_OP
181#define TARGET_ASM_ALIGNED_SI_OP "\t.dword\t"
182#undef TARGET_ASM_ALIGNED_DI_OP
183#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
184
185/* We need to define these, since the 2byte, 4byte, 8byte op:s are only
186 available in ELF. These "normal" pseudos do not have any alignment
187 constraints or side-effects. */
188#undef TARGET_ASM_UNALIGNED_HI_OP
189#define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
190
191#undef TARGET_ASM_UNALIGNED_SI_OP
192#define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
193
194#undef TARGET_ASM_UNALIGNED_DI_OP
195#define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
196
ed5c4a10
NF
197#undef TARGET_PRINT_OPERAND
198#define TARGET_PRINT_OPERAND cris_print_operand
199#undef TARGET_PRINT_OPERAND_ADDRESS
200#define TARGET_PRINT_OPERAND_ADDRESS cris_print_operand_address
201#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
202#define TARGET_PRINT_OPERAND_PUNCT_VALID_P cris_print_operand_punct_valid_p
203
5efd84c5
NF
204#undef TARGET_CONDITIONAL_REGISTER_USAGE
205#define TARGET_CONDITIONAL_REGISTER_USAGE cris_conditional_register_usage
206
c590b625
RH
207#undef TARGET_ASM_OUTPUT_MI_THUNK
208#define TARGET_ASM_OUTPUT_MI_THUNK cris_asm_output_mi_thunk
3961e8fe
RH
209#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
210#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
c590b625 211
1bc7c5b6
ZW
212#undef TARGET_ASM_FILE_START
213#define TARGET_ASM_FILE_START cris_file_start
214
c15c90bb
ZW
215#undef TARGET_INIT_LIBFUNCS
216#define TARGET_INIT_LIBFUNCS cris_init_libfuncs
217
d81db636
SB
218#undef TARGET_LRA_P
219#define TARGET_LRA_P hook_bool_void_false
220
a08160c3
AS
221#undef TARGET_LEGITIMATE_ADDRESS_P
222#define TARGET_LEGITIMATE_ADDRESS_P cris_legitimate_address_p
223
45dbdfd4
AS
224#undef TARGET_PREFERRED_RELOAD_CLASS
225#define TARGET_PREFERRED_RELOAD_CLASS cris_preferred_reload_class
226
a792c62c
HPN
227/* We don't define TARGET_FIXED_CONDITION_CODE_REGS, as at the time of
228 this writing, it has an effect only on pre-reload CSE and when
229 scheduling (and for "macro fusion" at that). Neither applies for
230 CRIS so don't waste compilation cycles on enabling a pass that does
231 nothing. Beware of changes to its usage; it may make sense to enable
232 "later". */
233
b3e01c3d
HPN
234#undef TARGET_CC_MODES_COMPATIBLE
235#define TARGET_CC_MODES_COMPATIBLE cris_cc_modes_compatible
236
a792c62c
HPN
237#undef TARGET_FLAGS_REGNUM
238#define TARGET_FLAGS_REGNUM CRIS_CC0_REGNUM
239
b95491a0
AS
240#undef TARGET_REGISTER_MOVE_COST
241#define TARGET_REGISTER_MOVE_COST cris_register_move_cost
242#undef TARGET_MEMORY_MOVE_COST
243#define TARGET_MEMORY_MOVE_COST cris_memory_move_cost
75642f32
RH
244#undef TARGET_RTX_COSTS
245#define TARGET_RTX_COSTS cris_rtx_costs
246#undef TARGET_ADDRESS_COST
247#define TARGET_ADDRESS_COST cris_address_cost
248
cde0f3fd
PB
249#undef TARGET_PROMOTE_FUNCTION_MODE
250#define TARGET_PROMOTE_FUNCTION_MODE cris_promote_function_mode
251
faee0106
HPN
252#undef TARGET_ATOMIC_ALIGN_FOR_MODE
253#define TARGET_ATOMIC_ALIGN_FOR_MODE cris_atomic_align_for_mode
254
c53e89f4
HPN
255#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
256#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
257
a2fef3a4
KH
258#undef TARGET_STRUCT_VALUE_RTX
259#define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx
558d352a
KH
260#undef TARGET_SETUP_INCOMING_VARARGS
261#define TARGET_SETUP_INCOMING_VARARGS cris_setup_incoming_varargs
8cd5a4e0
RH
262#undef TARGET_PASS_BY_REFERENCE
263#define TARGET_PASS_BY_REFERENCE cris_pass_by_reference
78a52f11
RH
264#undef TARGET_ARG_PARTIAL_BYTES
265#define TARGET_ARG_PARTIAL_BYTES cris_arg_partial_bytes
73f3f841
NF
266#undef TARGET_FUNCTION_ARG
267#define TARGET_FUNCTION_ARG cris_function_arg
268#undef TARGET_FUNCTION_INCOMING_ARG
269#define TARGET_FUNCTION_INCOMING_ARG cris_function_incoming_arg
270#undef TARGET_FUNCTION_ARG_ADVANCE
271#define TARGET_FUNCTION_ARG_ADVANCE cris_function_arg_advance
7ca35180
RH
272#undef TARGET_MD_ASM_ADJUST
273#define TARGET_MD_ASM_ADJUST cris_md_asm_adjust
ab4e53fe 274
b52b1749
AS
275#undef TARGET_FRAME_POINTER_REQUIRED
276#define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required
558d352a 277
c5387660
JM
278#undef TARGET_OPTION_OVERRIDE
279#define TARGET_OPTION_OVERRIDE cris_option_override
280
3e322b77
RH
281#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
282#define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template
283#undef TARGET_TRAMPOLINE_INIT
284#define TARGET_TRAMPOLINE_INIT cris_trampoline_init
285
4d696ad0
AS
286#undef TARGET_FUNCTION_VALUE
287#define TARGET_FUNCTION_VALUE cris_function_value
288#undef TARGET_LIBCALL_VALUE
289#define TARGET_LIBCALL_VALUE cris_libcall_value
2283c416
AS
290#undef TARGET_FUNCTION_VALUE_REGNO_P
291#define TARGET_FUNCTION_VALUE_REGNO_P cris_function_value_regno_p
4d696ad0 292
c43f4279
RS
293#undef TARGET_HARD_REGNO_NREGS
294#define TARGET_HARD_REGNO_NREGS cris_hard_regno_nregs
f939c3e6
RS
295#undef TARGET_HARD_REGNO_MODE_OK
296#define TARGET_HARD_REGNO_MODE_OK cris_hard_regno_mode_ok
297
f073de07
RS
298#undef TARGET_STATIC_RTX_ALIGNMENT
299#define TARGET_STATIC_RTX_ALIGNMENT cris_static_rtx_alignment
58e17cf8
RS
300#undef TARGET_CONSTANT_ALIGNMENT
301#define TARGET_CONSTANT_ALIGNMENT cris_constant_alignment
302
0b85d816
HPN
303struct gcc_target targetm = TARGET_INITIALIZER;
304
9a2ae08b
HPN
305namespace {
306
307const pass_data pass_data_cris_postdbr_cmpelim =
308{
309 RTL_PASS, /* type */
310 "mach2", /* name */
311 OPTGROUP_NONE, /* optinfo_flags */
312 TV_MACH_DEP, /* tv_id */
313 0, /* properties_required */
314 0, /* properties_provided */
315 0, /* properties_destroyed */
316 0, /* todo_flags_start */
317 0, /* todo_flags_finish */
318};
319
320class pass_cris_postdbr_cmpelim : public rtl_opt_pass
321{
322public:
323 pass_cris_postdbr_cmpelim (gcc::context *ctxt)
324 : rtl_opt_pass (pass_data_cris_postdbr_cmpelim, ctxt)
325 {}
326
327 /* opt_pass methods: */
328 virtual unsigned int execute (function *)
329 {
330 return cris_postdbr_cmpelim ();
331 }
332
333 /* No use running this if reorg and cmpelim aren't both run. */
334 virtual bool gate (function *)
335 {
336 return
337 optimize > 0
338 && flag_delayed_branch
339 && flag_compare_elim_after_reload;
340 }
341};
342
343} // anon namespace
344
345rtl_opt_pass *
346make_pass_cris_postdbr_cmpelim (gcc::context *ctxt)
347{
348 return new pass_cris_postdbr_cmpelim (ctxt);
349}
350
351/* "Cheap version" of cmpelim, making use of the opportunities opened up
352 by reorg.
353
354 Go through the insns of a function and look at each actual compare
355 insn; considering only those that compare a register to 0. If the
356 previous CC-affecting insn sets the compared register or if a move
357 reads from it, try to change that into a CC-setting move and try to
358 have it recognized. Bail at labels or non-matching insns that
359 clobber the compared register. If successful, delete the compare.
360
361 Also, reorg isn't up to date regarding data-flow handling, so we
362 can't go beyond classic RTL scanning. */
363
364static unsigned int
365cris_postdbr_cmpelim ()
366{
367 rtx_insn *insn;
368 rtx_insn *next;
369 rtx_insn *prev_cc_setter = 0;
370 rtx_insn *prev_cc_outer = 0;
371 rtx dccr = gen_rtx_REG (CCmode, CRIS_CC0_REGNUM);
372
373 /* Now look for compares in the insn stream. */
374 for (insn = get_insns (); insn; insn = next)
375 {
376 rtx_insn *outer_insn = insn;
377 rtx pat = PATTERN (insn);
378
379 next = NEXT_INSN (outer_insn);
380
381 /* Forget previous state when we see a label; we can't track or
382 merge its state. */
383 if (LABEL_P (insn))
384 {
385 prev_cc_setter = 0;
386 continue;
387 }
388
389 if (!NONDEBUG_INSN_P (insn))
390 continue;
391
392 /* Consider filled delay slots; there might be a comparison there.
393 It's only the second insn in a sequence that is interesting. */
394 if (GET_CODE (pat) == SEQUENCE)
f8feccb8 395 insn = as_a <rtx_insn *> (XVECEXP (pat, 0, 1));
9a2ae08b
HPN
396 /* The "else" eliminates temptations to consider an insn in a
397 delay slot for elimination; it can only be a prev_cc_setter. */
398 else if (prev_cc_setter != 0 && GET_CODE (pat) == SET)
399 {
400 rtx dest = SET_DEST (pat);
401 rtx src = SET_SRC (pat);
402 rtx prev_set;
403
404 if (REG_P (dest)
405 && REGNO (dest) == CRIS_CC0_REGNUM
406 && GET_CODE (src) == COMPARE
407 && REG_P (XEXP (src, 0))
408 && XEXP (src, 1) == const0_rtx
409 && (prev_set = single_set (prev_cc_setter)) != 0)
410 {
411 /* We have a candidate, and a prev_cc_setter to inspect. */
412 rtx reg = XEXP (src, 0);
413 rtx prev_dest = SET_DEST (prev_set);
414 rtx prev_src = SET_SRC (prev_set);
415 bool src_same = rtx_equal_p (prev_src, reg);
416
417 /* If the prev_cc_setter isn't a simple SET, or if the
418 compared register is modified in prev_cc_setter without
419 being the destination, or if it's modified between
420 prev_cc_setter (equal to or contained in prev_cc_outer)
421 and this insn, then we can't use the flags result. And
422 of course, the SET_DEST of prev_cc_setter (the main
423 interest, not dccr) has to be the same register and
424 mode we're interested in - or the SET_SRC. We've
425 already checked that the compared register isn't
426 changed in-between. */
427 if (REG_P (prev_dest)
428 && ! reg_set_p (reg, prev_src)
429 && ! reg_set_between_p (reg, prev_cc_outer, outer_insn)
430 && (src_same || rtx_equal_p (prev_dest, reg)))
431 {
432 machine_mode ccmode = GET_MODE (src);
433 rtx modeadjusted_dccr
434 = (ccmode == CCmode ? dccr
435 : gen_rtx_REG (CCmode, CRIS_CC0_REGNUM));
436 rtx compare
437 /* We don't need to copy_rtx pat: we're going to
438 delete that insn. */
439 = (src_same ? pat
440 : gen_rtx_SET (modeadjusted_dccr,
441 gen_rtx_COMPARE (ccmode,
442 copy_rtx (prev_src),
443 const0_rtx)));
444
445 /* Replace tentatively, the prev_set combo that is
446 ((set d s) (clobber dccr)) with
447 ((cmp s 0) (set d s)) where (cmp s 0) is the
448 compare we're looking at, and validate it or fail
449 the whole thing. First replace the ((set d s) ...)
450 with ((cmp s 0) ...)). */
451 validate_change (prev_cc_setter,
452 &XVECEXP (PATTERN (prev_cc_setter),
453 0, 0), compare, true);
454
455 /* Then the clobber with the (set d s). */
456 validate_change (prev_cc_setter,
457 &XVECEXP (PATTERN (prev_cc_setter),
458 0, 1), prev_set, true);
459
460 if (apply_change_group ())
461 {
462 delete_insn (insn);
463
464 /* We eliminated the compare. Then we must go to
465 the next insn: we can't consider the eliminated
466 insn for the next prev_cc_setter.
467
468 FIXME: if later insns still match, we could do
469 the delete_insn part only, for them. But, it
470 seems rare that reorg would manage to move a
471 second CC-clobber to another delay-slot,
472 leaving two identical compares (and presumably
473 users). */
474 prev_cc_setter = 0;
475 continue;
476 }
477 }
478 }
479 }
480
481 if (reg_set_p (dccr, insn))
482 {
483 rtx pat = PATTERN (insn);
484
485 prev_cc_setter = 0;
486
487 /* Make sure we can use it later on, otherwise forget it.
488 Don't look too close, we're going to pass a lot of these.
489 Just make sure the structure is that we can work with. */
490 if (GET_CODE (pat) == PARALLEL
491 && XVECLEN (pat, 0) == 2
492 && GET_CODE (XVECEXP (pat, 0, 1)) == CLOBBER)
493 {
494 prev_cc_setter = insn;
495 prev_cc_outer = outer_insn;
496 }
497 }
498 }
499
500 return 0;
501}
502
04539954
HPN
503/* Helper for cris_load_multiple_op and cris_ret_movem_op. */
504
68a81332 505bool
fb062a8b 506cris_movem_load_rest_p (rtx op)
04539954 507{
fb062a8b 508 unsigned int reg_count = XVECLEN (op, 0);
04539954
HPN
509 rtx src_addr;
510 int i;
511 rtx elt;
512 int setno;
513 int regno_dir = 1;
514 unsigned int regno = 0;
515
516 /* Perform a quick check so we don't blow up below. FIXME: Adjust for
517 other than (MEM reg). */
518 if (reg_count <= 1
fb062a8b
HPN
519 || GET_CODE (XVECEXP (op, 0, 0)) != SET
520 || !REG_P (SET_DEST (XVECEXP (op, 0, 0)))
521 || !MEM_P (SET_SRC (XVECEXP (op, 0, 0))))
68a81332 522 return false;
04539954
HPN
523
524 /* Check a possible post-inc indicator. */
fb062a8b
HPN
525 if (GET_CODE (XVECEXP (op, 0, 1)) == SET
526 && GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS)
04539954 527 {
fb062a8b
HPN
528 rtx reg = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 0);
529 rtx inc = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1);
04539954
HPN
530
531 reg_count--;
532
533 if (reg_count == 1
534 || !REG_P (reg)
fb062a8b
HPN
535 || !REG_P (SET_DEST (XVECEXP (op, 0, 1)))
536 || REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, 1)))
991c42ac 537 || !CONST_INT_P (inc)
04539954 538 || INTVAL (inc) != (HOST_WIDE_INT) reg_count * 4)
68a81332 539 return false;
fb062a8b 540 i = 2;
04539954
HPN
541 }
542 else
fb062a8b 543 i = 1;
04539954 544
d0780379
HPN
545 regno_dir = -1;
546 regno = reg_count - 1;
04539954 547
fb062a8b 548 elt = XVECEXP (op, 0, 0);
04539954
HPN
549 src_addr = XEXP (SET_SRC (elt), 0);
550
551 if (GET_CODE (elt) != SET
991c42ac 552 || !REG_P (SET_DEST (elt))
04539954
HPN
553 || GET_MODE (SET_DEST (elt)) != SImode
554 || REGNO (SET_DEST (elt)) != regno
991c42ac 555 || !MEM_P (SET_SRC (elt))
04539954
HPN
556 || GET_MODE (SET_SRC (elt)) != SImode
557 || !memory_address_p (SImode, src_addr))
68a81332 558 return false;
04539954
HPN
559
560 for (setno = 1; i < XVECLEN (op, 0); setno++, i++)
561 {
562 rtx elt = XVECEXP (op, 0, i);
563 regno += regno_dir;
564
565 if (GET_CODE (elt) != SET
991c42ac 566 || !REG_P (SET_DEST (elt))
04539954
HPN
567 || GET_MODE (SET_DEST (elt)) != SImode
568 || REGNO (SET_DEST (elt)) != regno
991c42ac 569 || !MEM_P (SET_SRC (elt))
04539954
HPN
570 || GET_MODE (SET_SRC (elt)) != SImode
571 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
572 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
991c42ac 573 || !CONST_INT_P (XEXP (XEXP (SET_SRC (elt), 0), 1))
04539954 574 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != setno * 4)
68a81332 575 return false;
04539954
HPN
576 }
577
68a81332 578 return true;
04539954
HPN
579}
580
68a81332
HPN
581/* Worker function for predicate for the parallel contents in a movem
582 to-memory. */
d29b4b1b 583
68a81332
HPN
584bool
585cris_store_multiple_op_p (rtx op)
d29b4b1b
HPN
586{
587 int reg_count = XVECLEN (op, 0);
588 rtx dest;
589 rtx dest_addr;
590 rtx dest_base;
591 int i;
592 rtx elt;
593 int setno;
594 int regno_dir = 1;
595 int regno = 0;
596 int offset = 0;
597
598 /* Perform a quick check so we don't blow up below. FIXME: Adjust for
599 other than (MEM reg) and (MEM (PLUS reg const)). */
600 if (reg_count <= 1)
68a81332 601 return false;
d29b4b1b
HPN
602
603 elt = XVECEXP (op, 0, 0);
604
605 if (GET_CODE (elt) != SET)
68a81332 606 return false;
d29b4b1b
HPN
607
608 dest = SET_DEST (elt);
609
991c42ac 610 if (!REG_P (SET_SRC (elt)) || !MEM_P (dest))
68a81332 611 return false;
d29b4b1b
HPN
612
613 dest_addr = XEXP (dest, 0);
614
615 /* Check a possible post-inc indicator. */
fb062a8b
HPN
616 if (GET_CODE (XVECEXP (op, 0, 1)) == SET
617 && GET_CODE (SET_SRC (XVECEXP (op, 0, 1))) == PLUS)
d29b4b1b
HPN
618 {
619 rtx reg = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 0);
620 rtx inc = XEXP (SET_SRC (XVECEXP (op, 0, 1)), 1);
621
622 reg_count--;
623
fb062a8b 624 if (!REG_P (reg)
d29b4b1b
HPN
625 || !REG_P (SET_DEST (XVECEXP (op, 0, 1)))
626 || REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, 1)))
991c42ac 627 || !CONST_INT_P (inc)
d29b4b1b
HPN
628 /* Support increment by number of registers, and by the offset
629 of the destination, if it has the form (MEM (PLUS reg
630 offset)). */
631 || !((REG_P (dest_addr)
632 && REGNO (dest_addr) == REGNO (reg)
633 && INTVAL (inc) == (HOST_WIDE_INT) reg_count * 4)
634 || (GET_CODE (dest_addr) == PLUS
635 && REG_P (XEXP (dest_addr, 0))
636 && REGNO (XEXP (dest_addr, 0)) == REGNO (reg)
991c42ac 637 && CONST_INT_P (XEXP (dest_addr, 1))
d29b4b1b 638 && INTVAL (XEXP (dest_addr, 1)) == INTVAL (inc))))
68a81332 639 return false;
d29b4b1b
HPN
640
641 i = 2;
642 }
643 else
644 i = 1;
645
d0780379
HPN
646 regno_dir = -1;
647 regno = reg_count - 1;
d29b4b1b
HPN
648
649 if (GET_CODE (elt) != SET
991c42ac 650 || !REG_P (SET_SRC (elt))
d29b4b1b
HPN
651 || GET_MODE (SET_SRC (elt)) != SImode
652 || REGNO (SET_SRC (elt)) != (unsigned int) regno
991c42ac 653 || !MEM_P (SET_DEST (elt))
d29b4b1b 654 || GET_MODE (SET_DEST (elt)) != SImode)
68a81332 655 return false;
d29b4b1b
HPN
656
657 if (REG_P (dest_addr))
658 {
659 dest_base = dest_addr;
660 offset = 0;
661 }
662 else if (GET_CODE (dest_addr) == PLUS
663 && REG_P (XEXP (dest_addr, 0))
991c42ac 664 && CONST_INT_P (XEXP (dest_addr, 1)))
d29b4b1b
HPN
665 {
666 dest_base = XEXP (dest_addr, 0);
667 offset = INTVAL (XEXP (dest_addr, 1));
668 }
669 else
68a81332 670 return false;
d29b4b1b
HPN
671
672 for (setno = 1; i < XVECLEN (op, 0); setno++, i++)
673 {
674 rtx elt = XVECEXP (op, 0, i);
675 regno += regno_dir;
676
677 if (GET_CODE (elt) != SET
991c42ac 678 || !REG_P (SET_SRC (elt))
d29b4b1b
HPN
679 || GET_MODE (SET_SRC (elt)) != SImode
680 || REGNO (SET_SRC (elt)) != (unsigned int) regno
991c42ac 681 || !MEM_P (SET_DEST (elt))
d29b4b1b
HPN
682 || GET_MODE (SET_DEST (elt)) != SImode
683 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
684 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_base)
991c42ac 685 || !CONST_INT_P (XEXP (XEXP (SET_DEST (elt), 0), 1))
d29b4b1b 686 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != setno * 4 + offset)
68a81332 687 return false;
d29b4b1b
HPN
688 }
689
68a81332 690 return true;
d29b4b1b
HPN
691}
692
5efd84c5 693/* The TARGET_CONDITIONAL_REGISTER_USAGE worker. */
0b85d816 694
5efd84c5 695static void
6640377c 696cris_conditional_register_usage (void)
0b85d816 697{
f60c7155
HPN
698 if (TARGET_HAS_MUL_INSNS)
699 fixed_regs[CRIS_MOF_REGNUM] = 0;
f9968e3e
HPN
700
701 /* On early versions, we must use the 16-bit condition-code register,
702 which has another name. */
703 if (cris_cpu_version < 8)
704 reg_names[CRIS_CC0_REGNUM] = "ccr";
0b85d816
HPN
705}
706
0b85d816
HPN
707/* Given an rtx, return the text string corresponding to the CODE of X.
708 Intended for use in the assembly language output section of a
709 define_insn. */
710
711const char *
6640377c 712cris_op_str (rtx x)
0b85d816
HPN
713{
714 cris_output_insn_is_bound = 0;
715 switch (GET_CODE (x))
716 {
717 case PLUS:
718 return "add";
0b85d816
HPN
719
720 case MINUS:
721 return "sub";
0b85d816
HPN
722
723 case MULT:
86da66b5
HPN
724 /* This function is for retrieving a part of an instruction name for
725 an operator, for immediate output. If that ever happens for
726 MULT, we need to apply TARGET_MUL_BUG in the caller. Make sure
727 we notice. */
31aa664a 728 internal_error ("MULT case in %<cris_op_str%>");
0b85d816
HPN
729 break;
730
731 case DIV:
732 return "div";
0b85d816
HPN
733
734 case AND:
735 return "and";
0b85d816
HPN
736
737 case IOR:
738 return "or";
0b85d816
HPN
739
740 case XOR:
741 return "xor";
0b85d816
HPN
742
743 case NOT:
744 return "not";
0b85d816
HPN
745
746 case ASHIFT:
747 return "lsl";
0b85d816
HPN
748
749 case LSHIFTRT:
750 return "lsr";
0b85d816
HPN
751
752 case ASHIFTRT:
753 return "asr";
0b85d816
HPN
754
755 case UMIN:
9c514326 756 /* Used to control the sign/zero-extend character for the 'E' modifier.
0b85d816
HPN
757 BOUND has none. */
758 cris_output_insn_is_bound = 1;
759 return "bound";
0b85d816
HPN
760
761 default:
762 return "Unknown operator";
0b85d816
HPN
763 }
764}
765
3d556836
HPN
766/* Emit an error message when we're in an asm, and a fatal error for
767 "normal" insns. Formatted output isn't easily implemented, since we
768 use output_operand_lossage to output the actual message and handle the
769 categorization of the error. */
770
771static void
6640377c 772cris_operand_lossage (const char *msgid, rtx op)
3d556836
HPN
773{
774 debug_rtx (op);
a52453cc 775 output_operand_lossage ("%s", msgid);
3d556836
HPN
776}
777
0b85d816
HPN
778/* Print an index part of an address to file. */
779
780static void
6640377c 781cris_print_index (rtx index, FILE *file)
0b85d816 782{
0b85d816
HPN
783 /* Make the index "additive" unless we'll output a negative number, in
784 which case the sign character is free (as in free beer). */
991c42ac 785 if (!CONST_INT_P (index) || INTVAL (index) >= 0)
0b85d816
HPN
786 putc ('+', file);
787
788 if (REG_P (index))
789 fprintf (file, "$%s.b", reg_names[REGNO (index)]);
d0780379 790 else if (CONSTANT_P (index))
0b85d816
HPN
791 cris_output_addr_const (file, index);
792 else if (GET_CODE (index) == MULT)
793 {
794 fprintf (file, "$%s.",
795 reg_names[REGNO (XEXP (index, 0))]);
796
797 putc (INTVAL (XEXP (index, 1)) == 2 ? 'w' : 'd', file);
798 }
9e19a50c 799 else if (GET_CODE (index) == SIGN_EXTEND && MEM_P (XEXP (index, 0)))
0b85d816 800 {
9e19a50c 801 rtx inner = XEXP (index, 0);
0b85d816
HPN
802 rtx inner_inner = XEXP (inner, 0);
803
804 if (GET_CODE (inner_inner) == POST_INC)
805 {
806 fprintf (file, "[$%s+].",
807 reg_names[REGNO (XEXP (inner_inner, 0))]);
808 putc (GET_MODE (inner) == HImode ? 'w' : 'b', file);
809 }
810 else
811 {
812 fprintf (file, "[$%s].", reg_names[REGNO (inner_inner)]);
813
814 putc (GET_MODE (inner) == HImode ? 'w' : 'b', file);
815 }
816 }
991c42ac 817 else if (MEM_P (index))
0b85d816 818 {
9e19a50c 819 rtx inner = XEXP (index, 0);
0b85d816
HPN
820 if (GET_CODE (inner) == POST_INC)
821 fprintf (file, "[$%s+].d", reg_names[REGNO (XEXP (inner, 0))]);
822 else
823 fprintf (file, "[$%s].d", reg_names[REGNO (inner)]);
824 }
825 else
117b0c0a 826 cris_operand_lossage ("unexpected index-type in cris_print_index",
3d556836 827 index);
0b85d816
HPN
828}
829
830/* Print a base rtx of an address to file. */
831
832static void
6640377c 833cris_print_base (rtx base, FILE *file)
0b85d816
HPN
834{
835 if (REG_P (base))
836 fprintf (file, "$%s", reg_names[REGNO (base)]);
837 else if (GET_CODE (base) == POST_INC)
d0780379 838 fprintf (file, "$%s+", reg_names[REGNO (XEXP (base, 0))]);
0b85d816 839 else
117b0c0a 840 cris_operand_lossage ("unexpected base-type in cris_print_base",
3d556836 841 base);
0b85d816
HPN
842}
843
844/* Usable as a guard in expressions. */
845
846int
6640377c 847cris_fatal (char *arg)
0b85d816
HPN
848{
849 internal_error (arg);
850
851 /* We'll never get here; this is just to appease compilers. */
852 return 0;
853}
854
04539954
HPN
855/* Return nonzero if REGNO is an ordinary register that *needs* to be
856 saved together with other registers, possibly by a MOVEM instruction,
857 or is saved for target-independent reasons. There may be
858 target-dependent reasons to save the register anyway; this is just a
859 wrapper for a complicated conditional. */
860
861static int
d0780379 862cris_reg_saved_in_regsave_area (unsigned int regno)
04539954
HPN
863{
864 return
6fb5fa3c 865 (((df_regs_ever_live_p (regno)
d0780379 866 && !call_used_or_fixed_reg_p (regno)))
aa27696b 867 && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed)
04539954 868 && regno != CRIS_SRP_REGNUM)
e3b5732b 869 || (crtl->calls_eh_return
04539954
HPN
870 && (regno == EH_RETURN_DATA_REGNO (0)
871 || regno == EH_RETURN_DATA_REGNO (1)
872 || regno == EH_RETURN_DATA_REGNO (2)
873 || regno == EH_RETURN_DATA_REGNO (3)));
874}
875
0b85d816
HPN
876/* The PRINT_OPERAND worker. */
877
ed5c4a10 878static void
6640377c 879cris_print_operand (FILE *file, rtx x, int code)
0b85d816
HPN
880{
881 rtx operand = x;
882
0b85d816
HPN
883 /* New code entries should just be added to the switch below. If
884 handling is finished, just return. If handling was just a
885 modification of the operand, the modified operand should be put in
886 "operand", and then do a break to let default handling
887 (zero-modifier) output the operand. */
888
889 switch (code)
890 {
891 case 'b':
59b9a953 892 /* Print the unsigned supplied integer as if it were signed
0b85d816 893 and < 0, i.e print 255 or 65535 as -1, 254, 65534 as -2, etc. */
06cadf63 894 if (!satisfies_constraint_O (x))
3d556836 895 LOSE_AND_RETURN ("invalid operand for 'b' modifier", x);
69487202
KG
896 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
897 INTVAL (x)| (INTVAL (x) <= 255 ? ~255 : ~65535));
0b85d816
HPN
898 return;
899
900 case 'x':
901 /* Print assembler code for operator. */
902 fprintf (file, "%s", cris_op_str (operand));
903 return;
904
04539954
HPN
905 case 'o':
906 {
907 /* A movem modifier working on a parallel; output the register
908 name. */
909 int regno;
910
911 if (GET_CODE (x) != PARALLEL)
912 LOSE_AND_RETURN ("invalid operand for 'o' modifier", x);
913
914 /* The second item can be (set reg (plus reg const)) to denote a
915 postincrement. */
916 regno
917 = (GET_CODE (SET_SRC (XVECEXP (x, 0, 1))) == PLUS
918 ? XVECLEN (x, 0) - 2
919 : XVECLEN (x, 0) - 1);
920
921 fprintf (file, "$%s", reg_names [regno]);
922 }
923 return;
924
925 case 'O':
926 {
927 /* A similar movem modifier; output the memory operand. */
928 rtx addr;
929
930 if (GET_CODE (x) != PARALLEL)
931 LOSE_AND_RETURN ("invalid operand for 'O' modifier", x);
932
933 /* The lowest mem operand is in the first item, but perhaps it
934 needs to be output as postincremented. */
991c42ac 935 addr = MEM_P (SET_SRC (XVECEXP (x, 0, 0)))
04539954
HPN
936 ? XEXP (SET_SRC (XVECEXP (x, 0, 0)), 0)
937 : XEXP (SET_DEST (XVECEXP (x, 0, 0)), 0);
938
d29b4b1b
HPN
939 /* The second item can be a (set reg (plus reg const)) to denote
940 a modification. */
04539954 941 if (GET_CODE (SET_SRC (XVECEXP (x, 0, 1))) == PLUS)
d29b4b1b
HPN
942 {
943 /* It's a post-increment, if the address is a naked (reg). */
944 if (REG_P (addr))
945 addr = gen_rtx_POST_INC (SImode, addr);
946 else
947 {
948 /* Otherwise, it's a side-effect; RN=RN+M. */
949 fprintf (file, "[$%s=$%s%s%d]",
950 reg_names [REGNO (SET_DEST (XVECEXP (x, 0, 1)))],
951 reg_names [REGNO (XEXP (addr, 0))],
952 INTVAL (XEXP (addr, 1)) < 0 ? "" : "+",
953 (int) INTVAL (XEXP (addr, 1)));
954 return;
955 }
956 }
cc8ca59e 957 output_address (VOIDmode, addr);
04539954
HPN
958 }
959 return;
960
0b85d816
HPN
961 case 'p':
962 /* Adjust a power of two to its log2. */
991c42ac 963 if (!CONST_INT_P (x) || exact_log2 (INTVAL (x)) < 0 )
3d556836 964 LOSE_AND_RETURN ("invalid operand for 'p' modifier", x);
0b85d816
HPN
965 fprintf (file, "%d", exact_log2 (INTVAL (x)));
966 return;
967
968 case 's':
969 /* For an integer, print 'b' or 'w' if <= 255 or <= 65535
970 respectively. This modifier also terminates the inhibiting
971 effects of the 'x' modifier. */
972 cris_output_insn_is_bound = 0;
991c42ac 973 if (GET_MODE (x) == VOIDmode && CONST_INT_P (x))
0b85d816
HPN
974 {
975 if (INTVAL (x) >= 0)
976 {
977 if (INTVAL (x) <= 255)
978 putc ('b', file);
979 else if (INTVAL (x) <= 65535)
980 putc ('w', file);
981 else
982 putc ('d', file);
983 }
984 else
985 putc ('d', file);
986 return;
987 }
988
989 /* For a non-integer, print the size of the operand. */
990 putc ((GET_MODE (x) == SImode || GET_MODE (x) == SFmode)
991 ? 'd' : GET_MODE (x) == HImode ? 'w'
992 : GET_MODE (x) == QImode ? 'b'
993 /* If none of the above, emit an erroneous size letter. */
994 : 'X',
995 file);
996 return;
997
998 case 'z':
999 /* Const_int: print b for -127 <= x <= 255,
b6c34129 1000 w for -32768 <= x <= 65535, else die. */
991c42ac 1001 if (!CONST_INT_P (x)
0b85d816 1002 || INTVAL (x) < -32768 || INTVAL (x) > 65535)
3d556836 1003 LOSE_AND_RETURN ("invalid operand for 'z' modifier", x);
0b85d816
HPN
1004 putc (INTVAL (x) >= -128 && INTVAL (x) <= 255 ? 'b' : 'w', file);
1005 return;
1006
1007 case '#':
1008 /* Output a 'nop' if there's nothing for the delay slot.
1009 This method stolen from the sparc files. */
1010 if (dbr_sequence_length () == 0)
1011 fputs ("\n\tnop", file);
1012 return;
1013
86da66b5
HPN
1014 case '!':
1015 /* Output directive for alignment padded with "nop" insns.
1016 Optimizing for size, it's plain 4-byte alignment, otherwise we
1017 align the section to a cache-line (32 bytes) and skip at max 2
1018 bytes, i.e. we skip if it's the last insn on a cache-line. The
1019 latter is faster by a small amount (for two test-programs 99.6%
1020 and 99.9%) and larger by a small amount (ditto 100.1% and
1021 100.2%). This is supposed to be the simplest yet performance-
1022 wise least intrusive way to make sure the immediately following
1023 (supposed) muls/mulu insn isn't located at the end of a
1024 cache-line. */
1025 if (TARGET_MUL_BUG)
1026 fputs (optimize_size
1027 ? ".p2alignw 2,0x050f\n\t"
1028 : ".p2alignw 5,0x050f,2\n\t", file);
1029 return;
1030
0b85d816
HPN
1031 case 'H':
1032 /* Print high (most significant) part of something. */
1033 switch (GET_CODE (operand))
1034 {
1035 case CONST_INT:
2239ced8
HPN
1036 /* If we're having 64-bit HOST_WIDE_INTs, the whole (DImode)
1037 value is kept here, and so may be other than 0 or -1. */
1038 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
1039 INTVAL (operand_subword (operand, 1, 0, DImode)));
0b85d816
HPN
1040 return;
1041
1042 case CONST_DOUBLE:
1043 /* High part of a long long constant. */
1044 if (GET_MODE (operand) == VOIDmode)
1045 {
69487202 1046 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_HIGH (x));
0b85d816
HPN
1047 return;
1048 }
1049 else
3d556836 1050 LOSE_AND_RETURN ("invalid operand for 'H' modifier", x);
0b85d816
HPN
1051
1052 case REG:
1053 /* Print reg + 1. Check that there's not an attempt to print
c31500c2
HPN
1054 high-parts of registers like stack-pointer or higher, except
1055 for SRP (where the "high part" is MOF). */
1056 if (REGNO (operand) > STACK_POINTER_REGNUM - 2
1057 && (REGNO (operand) != CRIS_SRP_REGNUM
1058 || CRIS_SRP_REGNUM + 1 != CRIS_MOF_REGNUM
1059 || fixed_regs[CRIS_MOF_REGNUM] != 0))
3d556836 1060 LOSE_AND_RETURN ("bad register", operand);
0b85d816
HPN
1061 fprintf (file, "$%s", reg_names[REGNO (operand) + 1]);
1062 return;
1063
1064 case MEM:
1065 /* Adjust memory address to high part. */
1066 {
1067 rtx adj_mem = operand;
1068 int size
1069 = GET_MODE_BITSIZE (GET_MODE (operand)) / BITS_PER_UNIT;
1070
1071 /* Adjust so we can use two SImode in DImode.
1072 Calling adj_offsettable_operand will make sure it is an
1073 offsettable address. Don't do this for a postincrement
1074 though; it should remain as it was. */
1075 if (GET_CODE (XEXP (adj_mem, 0)) != POST_INC)
1076 adj_mem
1077 = adjust_address (adj_mem, GET_MODE (adj_mem), size / 2);
1078
cc8ca59e 1079 output_address (VOIDmode, XEXP (adj_mem, 0));
0b85d816
HPN
1080 return;
1081 }
1082
1083 default:
3d556836 1084 LOSE_AND_RETURN ("invalid operand for 'H' modifier", x);
0b85d816
HPN
1085 }
1086
1087 case 'L':
1088 /* Strip the MEM expression. */
1089 operand = XEXP (operand, 0);
1090 break;
1091
1092 case 'e':
9c514326 1093 /* Like 'E', but ignore state set by 'x'. FIXME: Use code
3abcb3a7
HPN
1094 iterators and attributes in cris.md to avoid the need for %x
1095 and %E (and %e) and state passed between those modifiers. */
9c514326
HPN
1096 cris_output_insn_is_bound = 0;
1097 /* FALL THROUGH. */
1098 case 'E':
0b85d816
HPN
1099 /* Print 's' if operand is SIGN_EXTEND or 'u' if ZERO_EXTEND unless
1100 cris_output_insn_is_bound is nonzero. */
1101 if (GET_CODE (operand) != SIGN_EXTEND
1102 && GET_CODE (operand) != ZERO_EXTEND
991c42ac 1103 && !CONST_INT_P (operand))
3d556836 1104 LOSE_AND_RETURN ("invalid operand for 'e' modifier", x);
0b85d816
HPN
1105
1106 if (cris_output_insn_is_bound)
1107 {
1108 cris_output_insn_is_bound = 0;
1109 return;
1110 }
1111
1112 putc (GET_CODE (operand) == SIGN_EXTEND
991c42ac 1113 || (CONST_INT_P (operand) && INTVAL (operand) < 0)
0b85d816
HPN
1114 ? 's' : 'u', file);
1115 return;
1116
1117 case 'm':
1118 /* Print the size letter of the inner element. We can do it by
1119 calling ourselves with the 's' modifier. */
1120 if (GET_CODE (operand) != SIGN_EXTEND && GET_CODE (operand) != ZERO_EXTEND)
3d556836 1121 LOSE_AND_RETURN ("invalid operand for 'm' modifier", x);
0b85d816
HPN
1122 cris_print_operand (file, XEXP (operand, 0), 's');
1123 return;
1124
1125 case 'M':
1126 /* Print the least significant part of operand. */
1127 if (GET_CODE (operand) == CONST_DOUBLE)
1128 {
69487202 1129 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
0b85d816
HPN
1130 return;
1131 }
991c42ac 1132 else if (HOST_BITS_PER_WIDE_INT > 32 && CONST_INT_P (operand))
60ffa0e5 1133 {
69487202 1134 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
4a085d2e 1135 INTVAL (x) & ((unsigned int) 0x7fffffff * 2 + 1));
60ffa0e5
RH
1136 return;
1137 }
1138 /* Otherwise the least significant part equals the normal part,
1139 so handle it normally. */
0b85d816
HPN
1140 break;
1141
1142 case 'A':
1143 /* When emitting an add for the high part of a DImode constant, we
1144 want to use addq for 0 and adds.w for -1. */
991c42ac 1145 if (!CONST_INT_P (operand))
3d556836 1146 LOSE_AND_RETURN ("invalid operand for 'A' modifier", x);
0b85d816
HPN
1147 fprintf (file, INTVAL (operand) < 0 ? "adds.w" : "addq");
1148 return;
1149
24ddb79c
HPN
1150 case 'P':
1151 /* For const_int operands, print the additive mnemonic and the
1152 modified operand (byte-sized operands don't save anything):
1153 N=MIN_INT..-65536: add.d N
1154 -65535..-64: subu.w -N
1155 -63..-1: subq -N
1156 0..63: addq N
1157 64..65535: addu.w N
1158 65536..MAX_INT: add.d N.
1159 (Emitted mnemonics are capitalized to simplify testing.)
1160 For anything else (N.B: only register is valid), print "add.d". */
1161 if (REG_P (operand))
1162 {
1163 fprintf (file, "Add.d ");
1164
1165 /* Deal with printing the operand by dropping through to the
1166 normal path. */
1167 break;
1168 }
1169 else
1170 {
1171 int val;
1172 gcc_assert (CONST_INT_P (operand));
1173
1174 val = INTVAL (operand);
1175 if (!IN_RANGE (val, -65535, 65535))
1176 fprintf (file, "Add.d %d", val);
1177 else if (val <= -64)
1178 fprintf (file, "Subu.w %d", -val);
1179 else if (val <= -1)
1180 fprintf (file, "Subq %d", -val);
1181 else if (val <= 63)
1182 fprintf (file, "Addq %d", val);
1183 else if (val <= 65535)
1184 fprintf (file, "Addu.w %d", val);
1185 return;
1186 }
1187 break;
1188
1189 case 'q':
1190 /* If the operand is an integer -31..31, print "q" else ".d". */
1191 if (CONST_INT_P (operand) && IN_RANGE (INTVAL (operand), -31, 31))
1192 fprintf (file, "q");
1193 else
1194 fprintf (file, ".d");
1195 return;
1196
0b85d816
HPN
1197 case 'D':
1198 /* When emitting an sub for the high part of a DImode constant, we
1199 want to use subq for 0 and subs.w for -1. */
991c42ac 1200 if (!CONST_INT_P (operand))
3d556836 1201 LOSE_AND_RETURN ("invalid operand for 'D' modifier", x);
0b85d816
HPN
1202 fprintf (file, INTVAL (operand) < 0 ? "subs.w" : "subq");
1203 return;
1204
1205 case 'S':
1206 /* Print the operand as the index-part of an address.
1207 Easiest way out is to use cris_print_index. */
1208 cris_print_index (operand, file);
1209 return;
1210
1211 case 'T':
6cb68940
HPN
1212 {
1213 /* Print the size letter for an operand to a ASHIFT, which must be a
1214 const_int with a suitable value. */
1215 int shiftval;
1216
1217 if (!CONST_INT_P (operand))
1218 LOSE_AND_RETURN ("invalid operand for 'T' modifier", x);
1219
1220 shiftval = INTVAL (operand);
1221
1222 if (!(shiftval == 1 || shiftval == 2))
1223 LOSE_AND_RETURN ("invalid operand for 'T' modifier", x);
1224
1225 fprintf (file, "%s", shiftval == 1 ? ".w" : ".d");
1226 }
0b85d816
HPN
1227 return;
1228
1229 case 0:
e5837c07 1230 /* No code, print as usual. */
0b85d816
HPN
1231 break;
1232
1233 default:
3d556836 1234 LOSE_AND_RETURN ("invalid operand modifier letter", x);
0b85d816
HPN
1235 }
1236
e5837c07 1237 /* Print an operand as without a modifier letter. */
0b85d816
HPN
1238 switch (GET_CODE (operand))
1239 {
1240 case REG:
f60c7155
HPN
1241 if (REGNO (operand) > 15
1242 && REGNO (operand) != CRIS_MOF_REGNUM
f9968e3e
HPN
1243 && REGNO (operand) != CRIS_SRP_REGNUM
1244 && REGNO (operand) != CRIS_CC0_REGNUM)
c725bd79 1245 internal_error ("internal error: bad register: %d", REGNO (operand));
0b85d816
HPN
1246 fprintf (file, "$%s", reg_names[REGNO (operand)]);
1247 return;
1248
1249 case MEM:
cc8ca59e 1250 output_address (GET_MODE (operand), XEXP (operand, 0));
0b85d816
HPN
1251 return;
1252
1253 case CONST_DOUBLE:
1254 if (GET_MODE (operand) == VOIDmode)
1255 /* A long long constant. */
1256 output_addr_const (file, operand);
1257 else
1258 {
1259 /* Only single precision is allowed as plain operands the
34a72c33 1260 moment. */
0b85d816
HPN
1261 long l;
1262
1263 /* FIXME: Perhaps check overflow of the "single". */
34a72c33 1264 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operand), l);
0b85d816
HPN
1265
1266 fprintf (file, "0x%lx", l);
1267 }
1268 return;
1269
0b85d816
HPN
1270 case CONST:
1271 cris_output_addr_const (file, operand);
1272 return;
1273
1274 case MULT:
1275 case ASHIFT:
1276 {
1277 /* For a (MULT (reg X) const_int) we output "rX.S". */
991c42ac 1278 int i = CONST_INT_P (XEXP (operand, 1))
0b85d816 1279 ? INTVAL (XEXP (operand, 1)) : INTVAL (XEXP (operand, 0));
991c42ac 1280 rtx reg = CONST_INT_P (XEXP (operand, 1))
0b85d816
HPN
1281 ? XEXP (operand, 0) : XEXP (operand, 1);
1282
991c42ac
JBG
1283 if (!REG_P (reg)
1284 || (!CONST_INT_P (XEXP (operand, 0))
1285 && !CONST_INT_P (XEXP (operand, 1))))
3d556836 1286 LOSE_AND_RETURN ("unexpected multiplicative operand", x);
0b85d816
HPN
1287
1288 cris_print_base (reg, file);
1289 fprintf (file, ".%c",
1290 i == 0 || (i == 1 && GET_CODE (operand) == MULT) ? 'b'
1291 : i == 4 ? 'd'
1292 : (i == 2 && GET_CODE (operand) == MULT) || i == 1 ? 'w'
1293 : 'd');
1294 return;
1295 }
1296
1297 default:
1298 /* No need to handle all strange variants, let output_addr_const
1299 do it for us. */
d0780379 1300 if (CONSTANT_P (operand))
0b85d816
HPN
1301 {
1302 cris_output_addr_const (file, operand);
1303 return;
1304 }
1305
3d556836 1306 LOSE_AND_RETURN ("unexpected operand", x);
0b85d816
HPN
1307 }
1308}
1309
ed5c4a10
NF
1310static bool
1311cris_print_operand_punct_valid_p (unsigned char code)
1312{
d0780379 1313 return (code == '#' || code == '!');
ed5c4a10
NF
1314}
1315
0b85d816
HPN
1316/* The PRINT_OPERAND_ADDRESS worker. */
1317
ed5c4a10 1318static void
cc8ca59e 1319cris_print_operand_address (FILE *file, machine_mode /*mode*/, rtx x)
0b85d816
HPN
1320{
1321 /* All these were inside MEM:s so output indirection characters. */
1322 putc ('[', file);
1323
1324 if (CONSTANT_ADDRESS_P (x))
1325 cris_output_addr_const (file, x);
a08160c3 1326 else if (cris_base_or_autoincr_p (x, true))
0b85d816
HPN
1327 cris_print_base (x, file);
1328 else if (GET_CODE (x) == PLUS)
1329 {
1330 rtx x1, x2;
1331
1332 x1 = XEXP (x, 0);
1333 x2 = XEXP (x, 1);
a08160c3 1334 if (cris_base_p (x1, true))
0b85d816
HPN
1335 {
1336 cris_print_base (x1, file);
1337 cris_print_index (x2, file);
1338 }
a08160c3 1339 else if (cris_base_p (x2, true))
0b85d816
HPN
1340 {
1341 cris_print_base (x2, file);
1342 cris_print_index (x1, file);
1343 }
1344 else
3d556836 1345 LOSE_AND_RETURN ("unrecognized address", x);
0b85d816 1346 }
991c42ac 1347 else if (MEM_P (x))
0b85d816
HPN
1348 {
1349 /* A DIP. Output more indirection characters. */
1350 putc ('[', file);
1351 cris_print_base (XEXP (x, 0), file);
1352 putc (']', file);
1353 }
1354 else
3d556836 1355 LOSE_AND_RETURN ("unrecognized address", x);
0b85d816
HPN
1356
1357 putc (']', file);
1358}
1359
1360/* The RETURN_ADDR_RTX worker.
1361 We mark that the return address is used, either by EH or
1362 __builtin_return_address, for use by the function prologue and
1363 epilogue. FIXME: This isn't optimal; we just use the mark in the
1364 prologue and epilogue to say that the return address is to be stored
1365 in the stack frame. We could return SRP for leaf-functions and use the
1366 initial-value machinery. */
1367
1368rtx
6640377c 1369cris_return_addr_rtx (int count, rtx frameaddr ATTRIBUTE_UNUSED)
0b85d816
HPN
1370{
1371 cfun->machine->needs_return_address_on_stack = 1;
1372
1373 /* The return-address is stored just above the saved frame-pointer (if
1374 present). Apparently we can't eliminate from the frame-pointer in
1375 that direction, so use the incoming args (maybe pretended) pointer. */
1376 return count == 0
0a81f074 1377 ? gen_rtx_MEM (Pmode, plus_constant (Pmode, virtual_incoming_args_rtx, -4))
0b85d816
HPN
1378 : NULL_RTX;
1379}
1380
b2416742
HPN
1381/* Accessor used in cris.md:return because cfun->machine isn't available
1382 there. */
1383
04539954 1384bool
d29b4b1b 1385cris_return_address_on_stack (void)
b2416742 1386{
6fb5fa3c 1387 return df_regs_ever_live_p (CRIS_SRP_REGNUM)
04539954
HPN
1388 || cfun->machine->needs_return_address_on_stack;
1389}
1390
1391/* Accessor used in cris.md:return because cfun->machine isn't available
1392 there. */
1393
1394bool
d29b4b1b 1395cris_return_address_on_stack_for_return (void)
04539954
HPN
1396{
1397 return cfun->machine->return_type == CRIS_RETINSN_RET ? false
1398 : cris_return_address_on_stack ();
b2416742
HPN
1399}
1400
53680238 1401/* This handles FP -> SP elimination offset. */
0b85d816
HPN
1402
1403static int
6640377c 1404cris_initial_frame_pointer_offset (void)
0b85d816
HPN
1405{
1406 int regno;
1407
f710504c 1408 /* Initial offset is 0 if we don't have a frame pointer. */
0b85d816
HPN
1409 int offs = 0;
1410
1411 /* And 4 for each register pushed. */
1412 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
d0780379 1413 if (cris_reg_saved_in_regsave_area (regno))
0b85d816
HPN
1414 offs += 4;
1415
1416 /* And then, last, we add the locals allocated. */
1417 offs += get_frame_size ();
1418
1419 /* And more; the accumulated args size. */
38173d38 1420 offs += crtl->outgoing_args_size;
0b85d816
HPN
1421
1422 /* Then round it off, in case we use aligned stack. */
1423 if (TARGET_STACK_ALIGN)
1424 offs = TARGET_ALIGN_BY_32 ? (offs + 3) & ~3 : (offs + 1) & ~1;
1425
1426 return offs;
1427}
1428
1429/* The INITIAL_ELIMINATION_OFFSET worker.
1430 Calculate the difference between imaginary registers such as frame
1431 pointer and the stack pointer. Used to eliminate the frame pointer
1432 and imaginary arg pointer. */
1433
1434int
6640377c 1435cris_initial_elimination_offset (int fromreg, int toreg)
0b85d816
HPN
1436{
1437 int fp_sp_offset
1438 = cris_initial_frame_pointer_offset ();
1439
1440 /* We should be able to use regs_ever_live and related prologue
1441 information here, or alpha should not as well. */
04539954 1442 bool return_address_on_stack = cris_return_address_on_stack ();
0b85d816 1443
59b9a953 1444 /* Here we act as if the frame-pointer were needed. */
0b85d816
HPN
1445 int ap_fp_offset = 4 + (return_address_on_stack ? 4 : 0);
1446
1447 if (fromreg == ARG_POINTER_REGNUM
aa27696b 1448 && toreg == HARD_FRAME_POINTER_REGNUM)
0b85d816
HPN
1449 return ap_fp_offset;
1450
1451 /* Between the frame pointer and the stack are only "normal" stack
1452 variables and saved registers. */
1453 if (fromreg == FRAME_POINTER_REGNUM
1454 && toreg == STACK_POINTER_REGNUM)
1455 return fp_sp_offset;
1456
e5837c07 1457 /* We need to balance out the frame pointer here. */
0b85d816
HPN
1458 if (fromreg == ARG_POINTER_REGNUM
1459 && toreg == STACK_POINTER_REGNUM)
1460 return ap_fp_offset + fp_sp_offset - 4;
1461
aa27696b
HPN
1462 if (fromreg == FRAME_POINTER_REGNUM
1463 && toreg == HARD_FRAME_POINTER_REGNUM)
1464 return 0;
1465
b6c34129 1466 gcc_unreachable ();
0b85d816
HPN
1467}
1468
a08160c3
AS
1469/* Nonzero if X is a hard reg that can be used as an index. */
1470static inline bool
1471reg_ok_for_base_p (const_rtx x, bool strict)
1472{
1473 return ((! strict && ! HARD_REGISTER_P (x))
1474 || REGNO_OK_FOR_BASE_P (REGNO (x)));
1475}
1476
1477/* Nonzero if X is a hard reg that can be used as an index. */
1478static inline bool
1479reg_ok_for_index_p (const_rtx x, bool strict)
1480{
1481 return reg_ok_for_base_p (x, strict);
1482}
1483
a08160c3
AS
1484/* True if X is a valid base register. */
1485
1486bool
1487cris_base_p (const_rtx x, bool strict)
1488{
1489 return (REG_P (x) && reg_ok_for_base_p (x, strict));
1490}
1491
1492/* True if X is a valid index register. */
1493
1494static inline bool
1495cris_index_p (const_rtx x, bool strict)
1496{
1497 return (REG_P (x) && reg_ok_for_index_p (x, strict));
1498}
1499
1500/* True if X is a valid base register with or without autoincrement. */
1501
1502bool
1503cris_base_or_autoincr_p (const_rtx x, bool strict)
1504{
1505 return (cris_base_p (x, strict)
1506 || (GET_CODE (x) == POST_INC
d0780379 1507 && cris_base_p (XEXP (x, 0), strict)));
a08160c3
AS
1508}
1509
1510/* True if X is a valid (register) index for BDAP, i.e. [Rs].S or [Rs+].S. */
1511
1512bool
1513cris_bdap_index_p (const_rtx x, bool strict)
1514{
1515 return ((MEM_P (x)
1516 && GET_MODE (x) == SImode
1517 && cris_base_or_autoincr_p (XEXP (x, 0), strict))
1518 || (GET_CODE (x) == SIGN_EXTEND
1519 && MEM_P (XEXP (x, 0))
1520 && (GET_MODE (XEXP (x, 0)) == HImode
1521 || GET_MODE (XEXP (x, 0)) == QImode)
1522 && cris_base_or_autoincr_p (XEXP (XEXP (x, 0), 0), strict)));
1523}
1524
1525/* True if X is a valid (register) index for BIAP, i.e. Rd.m. */
1526
1527bool
1528cris_biap_index_p (const_rtx x, bool strict)
1529{
1530 return (cris_index_p (x, strict)
1531 || (GET_CODE (x) == MULT
1532 && cris_index_p (XEXP (x, 0), strict)
1533 && cris_scale_int_operand (XEXP (x, 1), VOIDmode)));
1534}
1535
d0780379 1536/* Worker function for TARGET_LEGITIMATE_ADDRESS_P. */
a08160c3 1537
a502bdb6 1538bool
ef4bddc2 1539cris_legitimate_address_p (machine_mode mode, rtx x, bool strict)
a08160c3
AS
1540{
1541 const_rtx x1, x2;
1542
1543 if (cris_base_or_autoincr_p (x, strict))
1544 return true;
d0780379 1545 else if (CONSTANT_P (x))
a08160c3
AS
1546 return true;
1547 /* Indexed? */
1548 else if (GET_CODE (x) == PLUS)
1549 {
1550 x1 = XEXP (x, 0);
1551 x2 = XEXP (x, 1);
1552 /* BDAP o, Rd. */
d0780379
HPN
1553 if ((cris_base_p (x1, strict) && CONSTANT_P (x2))
1554 || (cris_base_p (x2, strict) && CONSTANT_P (x1))
a08160c3
AS
1555 /* BDAP Rs[+], Rd. */
1556 || (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
1557 && ((cris_base_p (x1, strict)
1558 && cris_bdap_index_p (x2, strict))
1559 || (cris_base_p (x2, strict)
1560 && cris_bdap_index_p (x1, strict))
1561 /* BIAP.m Rs, Rd */
1562 || (cris_base_p (x1, strict)
1563 && cris_biap_index_p (x2, strict))
1564 || (cris_base_p (x2, strict)
1565 && cris_biap_index_p (x1, strict)))))
1566 return true;
1567 }
1568 else if (MEM_P (x))
1569 {
1570 /* DIP (Rs). Reject [[reg+]] and [[reg]] for DImode (long long). */
1571 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
1572 && cris_base_or_autoincr_p (XEXP (x, 0), strict))
1573 return true;
1574 }
1575
1576 return false;
1577}
1578
15883505
HPN
1579/* Worker function for LEGITIMIZE_RELOAD_ADDRESS. */
1580
1581bool
1582cris_reload_address_legitimized (rtx x,
ef4bddc2 1583 machine_mode mode ATTRIBUTE_UNUSED,
15883505
HPN
1584 int opnum ATTRIBUTE_UNUSED,
1585 int itype,
1586 int ind_levels ATTRIBUTE_UNUSED)
1587{
973c3795 1588 enum reload_type type = (enum reload_type) itype;
15883505 1589 rtx op0, op1;
15883505
HPN
1590 rtx *op1p;
1591
1592 if (GET_CODE (x) != PLUS)
1593 return false;
1594
1595 op0 = XEXP (x, 0);
15883505
HPN
1596 op1 = XEXP (x, 1);
1597 op1p = &XEXP (x, 1);
1598
1599 if (!REG_P (op1))
1600 return false;
1601
991c42ac 1602 if (GET_CODE (op0) == SIGN_EXTEND && MEM_P (XEXP (op0, 0)))
15883505
HPN
1603 {
1604 rtx op00 = XEXP (op0, 0);
1605 rtx op000 = XEXP (op00, 0);
1606 rtx *op000p = &XEXP (op00, 0);
1607
1608 if ((GET_MODE (op00) == HImode || GET_MODE (op00) == QImode)
1609 && (REG_P (op000)
1610 || (GET_CODE (op000) == POST_INC && REG_P (XEXP (op000, 0)))))
1611 {
1612 bool something_reloaded = false;
1613
1614 if (GET_CODE (op000) == POST_INC
1615 && REG_P (XEXP (op000, 0))
1616 && REGNO (XEXP (op000, 0)) > CRIS_LAST_GENERAL_REGISTER)
1617 /* No, this gets too complicated and is too rare to care
1618 about trying to improve on the general code Here.
1619 As the return-value is an all-or-nothing indicator, we
1620 punt on the other register too. */
1621 return false;
1622
1623 if ((REG_P (op000)
1624 && REGNO (op000) > CRIS_LAST_GENERAL_REGISTER))
1625 {
1626 /* The address of the inner mem is a pseudo or wrong
1627 reg: reload that. */
1628 push_reload (op000, NULL_RTX, op000p, NULL, GENERAL_REGS,
1629 GET_MODE (x), VOIDmode, 0, 0, opnum, type);
1630 something_reloaded = true;
1631 }
1632
1633 if (REGNO (op1) > CRIS_LAST_GENERAL_REGISTER)
1634 {
1635 /* Base register is a pseudo or wrong reg: reload it. */
1636 push_reload (op1, NULL_RTX, op1p, NULL, GENERAL_REGS,
1637 GET_MODE (x), VOIDmode, 0, 0,
1638 opnum, type);
1639 something_reloaded = true;
1640 }
1641
1642 gcc_assert (something_reloaded);
1643
1644 return true;
1645 }
1646 }
1647
1648 return false;
1649}
1650
45dbdfd4
AS
1651
1652/* Worker function for TARGET_PREFERRED_RELOAD_CLASS.
1653
1654 It seems like gcc (2.7.2 and 2.9x of 2000-03-22) may send "NO_REGS" as
1655 the class for a constant (testcase: __Mul in arit.c). To avoid forcing
1656 out a constant into the constant pool, we will trap this case and
1657 return something a bit more sane. FIXME: Check if this is a bug.
1658 Beware that we must not "override" classes that can be specified as
1659 constraint letters, or else asm operands using them will fail when
1660 they need to be reloaded. FIXME: Investigate whether that constitutes
1661 a bug. */
1662
1663static reg_class_t
07a6c52c 1664cris_preferred_reload_class (rtx x, reg_class_t rclass)
45dbdfd4 1665{
27e35bc4 1666 if (rclass != MOF_REGS
ff57d866 1667 && rclass != MOF_SRP_REGS
45dbdfd4
AS
1668 && rclass != SRP_REGS
1669 && rclass != CC0_REGS
1670 && rclass != SPECIAL_REGS)
27e35bc4 1671 return GENERAL_REGS;
45dbdfd4 1672
07a6c52c
HPN
1673 /* We can't make use of something that's not a general register when
1674 reloading an "eliminated" register (i.e. something that has turned into
1675 e.g. sp + const_int). */
1676 if (GET_CODE (x) == PLUS && !reg_class_subset_p (rclass, GENERAL_REGS))
1677 return NO_REGS;
1678
1679 /* Avoid putting constants into a special register, where the instruction is
1680 shorter if loaded into a general register. */
1681 if (satisfies_constraint_P (x) && !reg_class_subset_p (rclass, GENERAL_REGS))
1682 return NO_REGS;
1683
45dbdfd4
AS
1684 return rclass;
1685}
1686
b95491a0 1687/* Worker function for TARGET_REGISTER_MOVE_COST. */
0b85d816 1688
b95491a0 1689static int
ef4bddc2 1690cris_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
b95491a0 1691 reg_class_t from, reg_class_t to)
0b85d816 1692{
c31500c2
HPN
1693 /* Can't move to and from a SPECIAL_REGS register, so we have to say
1694 their move cost within that class is higher. How about 7? That's 3
1695 for a move to a GENERAL_REGS register, 3 for the move from the
1696 GENERAL_REGS register, and 1 for the increased register pressure.
9a7f14ef
HPN
1697 Also, it's higher than the memory move cost, as it should be. */
1698
1699 if (reg_classes_intersect_p (from, SPECIAL_REGS)
1700 && reg_classes_intersect_p (to, SPECIAL_REGS))
c31500c2
HPN
1701 return 7;
1702
2ea91d6b
HPN
1703 /* Make moves to/from SPECIAL_REGS slightly more expensive, as we
1704 generally prefer GENERAL_REGS. */
c31500c2
HPN
1705 if (reg_classes_intersect_p (from, SPECIAL_REGS)
1706 || reg_classes_intersect_p (to, SPECIAL_REGS))
1707 return 3;
1708
1709 return 2;
1710}
0b85d816 1711
b95491a0
AS
1712/* Worker function for TARGET_MEMORY_MOVE_COST.
1713
1714 This isn't strictly correct for v0..3 in buswidth-8bit mode, but should
1715 suffice. */
1716
1717static int
ef4bddc2 1718cris_memory_move_cost (machine_mode mode,
b95491a0
AS
1719 reg_class_t rclass ATTRIBUTE_UNUSED,
1720 bool in ATTRIBUTE_UNUSED)
1721{
1722 if (mode == QImode
1723 || mode == HImode)
1724 return 4;
1725 else
1726 return 6;
1727}
1728
b3e01c3d
HPN
1729/* Worker function for SELECT_CC_MODE. */
1730
1731machine_mode
1732cris_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1733{
1734 /* We have different sets of patterns before and after
1735 reload_completed, and everything before reload_completed is CCmode.
1736 At the time of this writing, this function isn't called before that
1737 time, so let's just gcc_assert on that assumption rather than doing
1738 "if (!reload_completed) return CCmode;". */
1739 gcc_assert (reload_completed);
1740
1741 /* For float mode or comparisons with something other than 0, we
1742 always go with CCmode. */
1743 if (GET_MODE_CLASS (GET_MODE (x)) != MODE_INT || y != const0_rtx)
1744 return CCmode;
1745
9596eccb
HPN
1746 /* If we have a comparison that doesn't have to look at V or C, return
1747 CC_NZmode. */
b3e01c3d
HPN
1748 if (op == EQ || op == NE || op == GTU || op == LEU
1749 || op == LT || op == GE)
9596eccb 1750 return CC_NZmode;
b3e01c3d
HPN
1751
1752 /* We should only get here for comparison operators. */
1753 gcc_assert (op == GEU || op == LTU || op == GT || op == LE);
1754
1755 return CC_NZVCmode;
1756}
1757
1758/* Worker function for TARGET_CC_MODES_COMPATIBLE.
1759 We start with CCmode for most comparisons, which merges and yields to
1760 CC_NZmode or CC_NZVCmode. The exceptions have CC_NZVCmode and can't do with
1761 another mode. */
1762
1763static machine_mode
1764cris_cc_modes_compatible (machine_mode m1, machine_mode m2)
1765{
1766 if (m1 == CC_NZVCmode)
1767 {
1768 if (m2 == CC_NZVCmode || m2 == CCmode)
1769 return CC_NZVCmode;
1770 return VOIDmode;
1771 }
1772
1773 if (m2 == CC_NZVCmode)
1774 {
1775 if (m1 == CC_NZVCmode || m1 == CCmode)
1776 return CC_NZVCmode;
1777 return VOIDmode;
1778 }
1779
1780 if (m1 != m2)
1781 return CC_NZmode;
1782
1783 return m1;
1784}
1785
0b85d816 1786/* Return != 0 if the return sequence for the current function is short,
04539954
HPN
1787 like "ret" or "jump [sp+]". Prior to reloading, we can't tell if
1788 registers must be saved, so return 0 then. */
0b85d816 1789
04539954 1790bool
6640377c 1791cris_simple_epilogue (void)
0b85d816 1792{
04539954
HPN
1793 unsigned int regno;
1794 unsigned int reglimit = STACK_POINTER_REGNUM;
0b85d816
HPN
1795
1796 if (! reload_completed
1797 || frame_pointer_needed
1798 || get_frame_size () != 0
38173d38
JH
1799 || crtl->args.pretend_args_size
1800 || crtl->args.size
1801 || crtl->outgoing_args_size
e3b5732b 1802 || crtl->calls_eh_return
0b85d816
HPN
1803
1804 /* If we're not supposed to emit prologue and epilogue, we must
1805 not emit return-type instructions. */
1806 || !TARGET_PROLOGUE_EPILOGUE)
04539954 1807 return false;
0b85d816 1808
04539954 1809 /* No simple epilogue if there are saved registers. */
0b85d816 1810 for (regno = 0; regno < reglimit; regno++)
d0780379 1811 if (cris_reg_saved_in_regsave_area (regno))
04539954 1812 return false;
0b85d816 1813
04539954
HPN
1814 return true;
1815}
1816
21ed4444
HPN
1817/* Emit checking that MEM is aligned for an access in MODE, failing
1818 that, executing a "break 8" (or call to abort, if "break 8" is
1819 disabled). */
1820
1821void
1822cris_emit_trap_for_misalignment (rtx mem)
1823{
9f215bf5
DM
1824 rtx addr, reg, ok_label, andop;
1825 rtx_insn *jmp;
21ed4444
HPN
1826 int natural_alignment;
1827 gcc_assert (MEM_P (mem));
1828
1829 natural_alignment = GET_MODE_SIZE (GET_MODE (mem));
1830 addr = XEXP (mem, 0);
1831 reg = force_reg (Pmode, addr);
1832 ok_label = gen_label_rtx ();
1833
1834 /* This will yield a btstq without a separate register used, usually -
1835 with the exception for PRE hoisting the "and" but not the branch
f02827cd 1836 around the trap: see testsuite/gcc.target/cris/sync-3s.c. */
2f352e3d
HPN
1837 andop = gen_rtx_AND (Pmode, reg, GEN_INT (natural_alignment - 1));
1838 emit_cmp_and_jump_insns (force_reg (SImode, andop), const0_rtx, EQ,
21ed4444
HPN
1839 NULL_RTX, Pmode, 1, ok_label);
1840 jmp = get_last_insn ();
1841 gcc_assert (JUMP_P (jmp));
1842
f02827cd 1843 predict_insn_def (jmp, PRED_NORETURN, TAKEN);
21ed4444
HPN
1844 expand_builtin_trap ();
1845 emit_label (ok_label);
1846}
1847
04539954
HPN
1848/* Expand a return insn (just one insn) marked as using SRP or stack
1849 slot depending on parameter ON_STACK. */
1850
1851void
1852cris_expand_return (bool on_stack)
1853{
1854 /* FIXME: emit a parallel with a USE for SRP or the stack-slot, to
1855 tell "ret" from "jump [sp+]". Some, but not all, other parts of
1856 GCC expect just (return) to do the right thing when optimizing, so
1857 we do that until they're fixed. Currently, all return insns in a
1858 function must be the same (not really a limiting factor) so we need
1859 to check that it doesn't change half-way through. */
3810076b 1860 emit_jump_insn (ret_rtx);
04539954 1861
b6c34129
HPN
1862 CRIS_ASSERT (cfun->machine->return_type != CRIS_RETINSN_RET || !on_stack);
1863 CRIS_ASSERT (cfun->machine->return_type != CRIS_RETINSN_JUMP || on_stack);
04539954
HPN
1864
1865 cfun->machine->return_type
1866 = on_stack ? CRIS_RETINSN_JUMP : CRIS_RETINSN_RET;
0b85d816
HPN
1867}
1868
3c50106f
RH
1869/* Compute a (partial) cost for rtx X. Return true if the complete
1870 cost has been computed, and false if subexpressions should be
1871 scanned. In either case, *TOTAL contains the cost result. */
1872
1873static bool
e548c9df
AM
1874cris_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
1875 int *total, bool speed)
3c50106f 1876{
e548c9df
AM
1877 int code = GET_CODE (x);
1878
3c50106f
RH
1879 switch (code)
1880 {
1881 case CONST_INT:
1882 {
1883 HOST_WIDE_INT val = INTVAL (x);
1884 if (val == 0)
1885 *total = 0;
1886 else if (val < 32 && val >= -32)
1887 *total = 1;
1888 /* Eight or 16 bits are a word and cycle more expensive. */
1889 else if (val <= 32767 && val >= -32768)
1890 *total = 2;
a7b376ee 1891 /* A 32-bit constant (or very seldom, unsigned 16 bits) costs
3c50106f
RH
1892 another word. FIXME: This isn't linear to 16 bits. */
1893 else
1894 *total = 4;
1895 return true;
1896 }
1897
1898 case LABEL_REF:
1899 *total = 6;
1900 return true;
1901
1902 case CONST:
1903 case SYMBOL_REF:
c00fc5cf 1904 *total = 6;
3c50106f
RH
1905 return true;
1906
1907 case CONST_DOUBLE:
e548c9df 1908 if (x != CONST0_RTX (mode == VOIDmode ? DImode : mode))
3c50106f
RH
1909 *total = 12;
1910 else
1911 /* Make 0.0 cheap, else test-insns will not be used. */
1912 *total = 0;
1913 return true;
1914
1915 case MULT:
aa05ad86
HPN
1916 /* If we have one arm of an ADDI, make sure it gets the cost of
1917 one insn, i.e. zero cost for this operand, and just the cost
1918 of the PLUS, as the insn is created by combine from a PLUS
1919 and an ASHIFT, and the MULT cost below would make the
1920 combined value be larger than the separate insns. The insn
1921 validity is checked elsewhere by combine.
1922
1923 FIXME: this case is a stop-gap for 4.3 and 4.4, this whole
1924 function should be rewritten. */
a08160c3 1925 if (outer_code == PLUS && cris_biap_index_p (x, false))
aa05ad86
HPN
1926 {
1927 *total = 0;
1928 return true;
1929 }
1930
3c50106f
RH
1931 /* Identify values that are no powers of two. Powers of 2 are
1932 taken care of already and those values should not be changed. */
991c42ac 1933 if (!CONST_INT_P (XEXP (x, 1))
3c50106f
RH
1934 || exact_log2 (INTVAL (XEXP (x, 1)) < 0))
1935 {
1936 /* If we have a multiply insn, then the cost is between
1937 1 and 2 "fast" instructions. */
1938 if (TARGET_HAS_MUL_INSNS)
1939 {
1940 *total = COSTS_N_INSNS (1) + COSTS_N_INSNS (1) / 2;
1941 return true;
1942 }
1943
1944 /* Estimate as 4 + 4 * #ofbits. */
1945 *total = COSTS_N_INSNS (132);
1946 return true;
1947 }
1948 return false;
1949
1950 case UDIV:
1951 case MOD:
1952 case UMOD:
1953 case DIV:
991c42ac 1954 if (!CONST_INT_P (XEXP (x, 1))
5b296d93 1955 || exact_log2 (INTVAL (XEXP (x, 1)) < 0))
3c50106f
RH
1956 {
1957 /* Estimate this as 4 + 8 * #of bits. */
1958 *total = COSTS_N_INSNS (260);
1959 return true;
1960 }
1961 return false;
1962
1963 case AND:
991c42ac 1964 if (CONST_INT_P (XEXP (x, 1))
3c50106f 1965 /* Two constants may actually happen before optimization. */
991c42ac 1966 && !CONST_INT_P (XEXP (x, 0))
06cadf63 1967 && !satisfies_constraint_I (XEXP (x, 1)))
3c50106f 1968 {
973c3795 1969 *total
e548c9df 1970 = (rtx_cost (XEXP (x, 0), mode, (enum rtx_code) outer_code,
68f932c4 1971 opno, speed) + 2
e548c9df 1972 + 2 * GET_MODE_NUNITS (mode));
3c50106f
RH
1973 return true;
1974 }
1975 return false;
1976
f90b7a5a 1977 case ZERO_EXTRACT:
b73bf8a1
HPN
1978 /* Conditionals are split after reload, giving a different look. */
1979 if (reload_completed)
1980 {
1981 if (outer_code != COMPARE)
1982 return false;
1983 }
1984 else
1985 switch (outer_code)
1986 {
1987 case EQ:
1988 case NE:
1989 case LT:
1990 case LTU:
1991 case LE:
1992 case LEU:
1993 case GT:
1994 case GTU:
1995 case GE:
1996 case GEU:
1997 break;
1998
1999 default:
2000 return false;
2001 }
f90b7a5a
PB
2002 /* fall through */
2003
3c50106f 2004 case ZERO_EXTEND: case SIGN_EXTEND:
e548c9df
AM
2005 *total = rtx_cost (XEXP (x, 0), VOIDmode, (enum rtx_code) outer_code,
2006 opno, speed);
3c50106f
RH
2007 return true;
2008
2009 default:
2010 return false;
2011 }
2012}
2013
0b85d816
HPN
2014/* The ADDRESS_COST worker. */
2015
75642f32 2016static int
ef4bddc2 2017cris_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
b413068c
OE
2018 addr_space_t as ATTRIBUTE_UNUSED,
2019 bool speed ATTRIBUTE_UNUSED)
0b85d816
HPN
2020{
2021 /* The metric to use for the cost-macros is unclear.
2022 The metric used here is (the number of cycles needed) / 2,
2023 where we consider equal a cycle for a word of code and a cycle to
a3ef2349 2024 read memory. FIXME: Adding "+ 1" to all values would avoid
e53b6e56 2025 returning 0, as tree-ssa-loop-ivopts.cc as of r128272 "normalizes"
a3ef2349
HPN
2026 0 to 1, thereby giving equal costs to [rN + rM] and [rN].
2027 Unfortunately(?) such a hack would expose other pessimizations,
2028 at least with g++.dg/tree-ssa/ivopts-1.C, adding insns to the
2029 loop there, without apparent reason. */
0b85d816
HPN
2030
2031 /* The cheapest addressing modes get 0, since nothing extra is needed. */
a08160c3 2032 if (cris_base_or_autoincr_p (x, false))
0b85d816
HPN
2033 return 0;
2034
2035 /* An indirect mem must be a DIP. This means two bytes extra for code,
2036 and 4 bytes extra for memory read, i.e. (2 + 4) / 2. */
991c42ac 2037 if (MEM_P (x))
0b85d816
HPN
2038 return (2 + 4) / 2;
2039
2040 /* Assume (2 + 4) / 2 for a single constant; a dword, since it needs
c00fc5cf 2041 an extra DIP prefix and 4 bytes of constant in most cases. */
0b85d816 2042 if (CONSTANT_P (x))
c00fc5cf 2043 return (2 + 4) / 2;
0b85d816
HPN
2044
2045 /* Handle BIAP and BDAP prefixes. */
2046 if (GET_CODE (x) == PLUS)
2047 {
2048 rtx tem1 = XEXP (x, 0);
2049 rtx tem2 = XEXP (x, 1);
2050
582be0a1
HPN
2051 /* Local extended canonicalization rule: the first operand must
2052 be REG, unless it's an operation (MULT). */
2053 if (!REG_P (tem1) && GET_CODE (tem1) != MULT)
2054 tem1 = tem2, tem2 = XEXP (x, 0);
2055
2056 /* We'll "assume" we have canonical RTX now. */
a3ef2349 2057 gcc_assert (REG_P (tem1) || GET_CODE (tem1) == MULT);
0b85d816 2058
a3ef2349
HPN
2059 /* A BIAP is 2 extra bytes for the prefix insn, nothing more. We
2060 recognize the typical MULT which is always in tem1 because of
2061 insn canonicalization. */
a08160c3 2062 if ((GET_CODE (tem1) == MULT && cris_biap_index_p (tem1, false))
a3ef2349
HPN
2063 || REG_P (tem2))
2064 return 2 / 2;
2065
2066 /* A BDAP (quick) is 2 extra bytes. Any constant operand to the
2067 PLUS is always found in tem2. */
2068 if (CONST_INT_P (tem2) && INTVAL (tem2) < 128 && INTVAL (tem2) >= -128)
2069 return 2 / 2;
2070
2071 /* A BDAP -32768 .. 32767 is like BDAP quick, but with 2 extra
2072 bytes. */
06cadf63 2073 if (satisfies_constraint_L (tem2))
a3ef2349
HPN
2074 return (2 + 2) / 2;
2075
2076 /* A BDAP with some other constant is 2 bytes extra. */
d0780379 2077 if (CONSTANT_P (tem2))
a3ef2349
HPN
2078 return (2 + 2 + 2) / 2;
2079
2080 /* BDAP with something indirect should have a higher cost than
2081 BIAP with register. FIXME: Should it cost like a MEM or more? */
2082 return (2 + 2 + 2) / 2;
2083 }
0b85d816
HPN
2084
2085 /* What else? Return a high cost. It matters only for valid
2086 addressing modes. */
2087 return 10;
2088}
2089
2090/* Check various objections to the side-effect. Used in the test-part
2091 of an anonymous insn describing an insn with a possible side-effect.
2092 Returns nonzero if the implied side-effect is ok.
2093
2094 code : PLUS or MULT
2095 ops : An array of rtx:es. lreg, rreg, rval,
2096 The variables multop and other_op are indexes into this,
2097 or -1 if they are not applicable.
2098 lreg : The register that gets assigned in the side-effect.
2099 rreg : One register in the side-effect expression
2100 rval : The other register, or an int.
2101 multop : An integer to multiply rval with.
2102 other_op : One of the entities of the main effect,
2103 whose mode we must consider. */
2104
2105int
6640377c
SB
2106cris_side_effect_mode_ok (enum rtx_code code, rtx *ops,
2107 int lreg, int rreg, int rval,
2108 int multop, int other_op)
0b85d816
HPN
2109{
2110 /* Find what value to multiply with, for rx =ry + rz * n. */
2111 int mult = multop < 0 ? 1 : INTVAL (ops[multop]);
2112
2113 rtx reg_rtx = ops[rreg];
2114 rtx val_rtx = ops[rval];
2115
2116 /* The operands may be swapped. Canonicalize them in reg_rtx and
2117 val_rtx, where reg_rtx always is a reg (for this constraint to
2118 match). */
a08160c3 2119 if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed))
0b85d816
HPN
2120 reg_rtx = val_rtx, val_rtx = ops[rreg];
2121
2122 /* Don't forget to check that reg_rtx really is a reg. If it isn't,
2123 we have no business. */
a08160c3 2124 if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed))
0b85d816
HPN
2125 return 0;
2126
2127 /* Don't do this when -mno-split. */
2128 if (!TARGET_SIDE_EFFECT_PREFIXES)
2129 return 0;
2130
2131 /* The mult expression may be hidden in lreg. FIXME: Add more
2132 commentary about that. */
2133 if (GET_CODE (val_rtx) == MULT)
2134 {
2135 mult = INTVAL (XEXP (val_rtx, 1));
2136 val_rtx = XEXP (val_rtx, 0);
2137 code = MULT;
2138 }
2139
2140 /* First check the "other operand". */
2141 if (other_op >= 0)
2142 {
2143 if (GET_MODE_SIZE (GET_MODE (ops[other_op])) > UNITS_PER_WORD)
2144 return 0;
2145
2146 /* Check if the lvalue register is the same as the "other
2147 operand". If so, the result is undefined and we shouldn't do
2148 this. FIXME: Check again. */
a08160c3
AS
2149 if ((cris_base_p (ops[lreg], reload_in_progress || reload_completed)
2150 && cris_base_p (ops[other_op],
2151 reload_in_progress || reload_completed)
0b85d816
HPN
2152 && REGNO (ops[lreg]) == REGNO (ops[other_op]))
2153 || rtx_equal_p (ops[other_op], ops[lreg]))
2154 return 0;
2155 }
2156
2157 /* Do not accept frame_pointer_rtx as any operand. */
2158 if (ops[lreg] == frame_pointer_rtx || ops[rreg] == frame_pointer_rtx
2159 || ops[rval] == frame_pointer_rtx
2160 || (other_op >= 0 && ops[other_op] == frame_pointer_rtx))
2161 return 0;
2162
2163 if (code == PLUS
a08160c3 2164 && ! cris_base_p (val_rtx, reload_in_progress || reload_completed))
0b85d816
HPN
2165 {
2166
2167 /* Do not allow rx = rx + n if a normal add or sub with same size
2168 would do. */
2169 if (rtx_equal_p (ops[lreg], reg_rtx)
991c42ac 2170 && CONST_INT_P (val_rtx)
0b85d816
HPN
2171 && (INTVAL (val_rtx) <= 63 && INTVAL (val_rtx) >= -63))
2172 return 0;
2173
c00fc5cf 2174 /* Check allowed cases, like [r(+)?].[bwd] and const. */
d0780379 2175 if (CONSTANT_P (val_rtx))
c00fc5cf 2176 return 1;
0b85d816 2177
a08160c3
AS
2178 if (MEM_P (val_rtx)
2179 && cris_base_or_autoincr_p (XEXP (val_rtx, 0),
2180 reload_in_progress || reload_completed))
0b85d816
HPN
2181 return 1;
2182
2183 if (GET_CODE (val_rtx) == SIGN_EXTEND
991c42ac 2184 && MEM_P (XEXP (val_rtx, 0))
a08160c3
AS
2185 && cris_base_or_autoincr_p (XEXP (XEXP (val_rtx, 0), 0),
2186 reload_in_progress || reload_completed))
0b85d816
HPN
2187 return 1;
2188
2189 /* If we got here, it's not a valid addressing mode. */
2190 return 0;
2191 }
2192 else if (code == MULT
a08160c3
AS
2193 || (code == PLUS
2194 && cris_base_p (val_rtx,
2195 reload_in_progress || reload_completed)))
0b85d816
HPN
2196 {
2197 /* Do not allow rx = rx + ry.S, since it doesn't give better code. */
2198 if (rtx_equal_p (ops[lreg], reg_rtx)
2199 || (mult == 1 && rtx_equal_p (ops[lreg], val_rtx)))
2200 return 0;
2201
2202 /* Do not allow bad multiply-values. */
2203 if (mult != 1 && mult != 2 && mult != 4)
2204 return 0;
2205
2206 /* Only allow r + ... */
a08160c3 2207 if (! cris_base_p (reg_rtx, reload_in_progress || reload_completed))
0b85d816
HPN
2208 return 0;
2209
2210 /* If we got here, all seems ok.
2211 (All checks need to be done above). */
2212 return 1;
2213 }
2214
2215 /* If we get here, the caller got its initial tests wrong. */
31aa664a 2216 internal_error ("internal error: %<cris_side_effect_mode_ok%> with bad operands");
0b85d816
HPN
2217}
2218
a8781821 2219/* Queue an .ident string in the queue of top-level asm statements.
e53b6e56 2220 If the front-end is done, we must be being called from toplev.cc.
a8781821
SB
2221 In that case, do nothing. */
2222void
2223cris_asm_output_ident (const char *string)
2224{
3dafb85c 2225 if (symtab->state != PARSING)
a8781821
SB
2226 return;
2227
2228 default_asm_output_ident_directive (string);
2229}
2230
c31500c2
HPN
2231/* The ASM_OUTPUT_CASE_END worker. */
2232
2233void
1f00691e 2234cris_asm_output_case_end (FILE *stream, int num, rtx_insn *table)
c31500c2 2235{
a50023f9
HPN
2236 /* Step back, over the label for the table, to the actual casejump and
2237 assert that we find only what's expected. */
1f00691e 2238 rtx_insn *whole_jump_insn = prev_nonnote_nondebug_insn (table);
a50023f9 2239 gcc_assert (whole_jump_insn != NULL_RTX && LABEL_P (whole_jump_insn));
d0780379 2240
a50023f9 2241 whole_jump_insn = prev_nonnote_nondebug_insn (whole_jump_insn);
d0780379
HPN
2242 gcc_assert (whole_jump_insn != NULL_RTX && JUMP_P (whole_jump_insn));
2243
a50023f9 2244 /* Get the pattern of the casejump, so we can extract the default label. */
1f00691e 2245 rtx whole_jump_pat = PATTERN (whole_jump_insn);
a50023f9 2246
c31500c2
HPN
2247 asm_fprintf (stream,
2248 "\t.word %LL%d-%LL%d%s\n",
2249 CODE_LABEL_NUMBER (XEXP
2250 (XEXP
1f00691e 2251 (XEXP (XVECEXP (whole_jump_pat, 0, 0), 1),
c31500c2
HPN
2252 2), 0)),
2253 num,
2254 (TARGET_PDEBUG ? "; default" : ""));
0b85d816
HPN
2255}
2256
c5387660 2257/* The TARGET_OPTION_OVERRIDE worker.
0b85d816
HPN
2258 As is the norm, this also parses -mfoo=bar type parameters. */
2259
c5387660
JM
2260static void
2261cris_option_override (void)
0b85d816
HPN
2262{
2263 if (cris_max_stackframe_str)
2264 {
2265 cris_max_stackframe = atoi (cris_max_stackframe_str);
2266
2267 /* Do some sanity checking. */
2268 if (cris_max_stackframe < 0 || cris_max_stackframe > 0x20000000)
a3f9f006
ML
2269 internal_error ("%<-max-stackframe=%d%> is not usable, "
2270 "not between 0 and %d",
0b85d816
HPN
2271 cris_max_stackframe, 0x20000000);
2272 }
2273
2274 /* Let "-metrax4" and "-metrax100" change the cpu version. */
2275 if (TARGET_SVINTO && cris_cpu_version < CRIS_CPU_SVINTO)
2276 cris_cpu_version = CRIS_CPU_SVINTO;
2277 else if (TARGET_ETRAX4_ADD && cris_cpu_version < CRIS_CPU_ETRAX4)
2278 cris_cpu_version = CRIS_CPU_ETRAX4;
2279
2280 /* Parse -march=... and its synonym, the deprecated -mcpu=... */
2281 if (cris_cpu_str)
2282 {
2283 cris_cpu_version
2284 = (*cris_cpu_str == 'v' ? atoi (cris_cpu_str + 1) : -1);
2285
2286 if (strcmp ("etrax4", cris_cpu_str) == 0)
2287 cris_cpu_version = 3;
2288
2289 if (strcmp ("svinto", cris_cpu_str) == 0
2290 || strcmp ("etrax100", cris_cpu_str) == 0)
2291 cris_cpu_version = 8;
2292
2293 if (strcmp ("ng", cris_cpu_str) == 0
2294 || strcmp ("etrax100lx", cris_cpu_str) == 0)
2295 cris_cpu_version = 10;
2296
d0780379 2297 if (cris_cpu_version < 0 || cris_cpu_version > 10)
a3f9f006 2298 error ("unknown CRIS version specification in %<-march=%> or "
31aa664a 2299 "%<-mcpu=%>: %s", cris_cpu_str);
0b85d816
HPN
2300
2301 /* Set the target flags. */
2302 if (cris_cpu_version >= CRIS_CPU_ETRAX4)
2a186d97 2303 target_flags |= MASK_ETRAX4_ADD;
0b85d816
HPN
2304
2305 /* If this is Svinto or higher, align for 32 bit accesses. */
2306 if (cris_cpu_version >= CRIS_CPU_SVINTO)
2307 target_flags
2a186d97
HPN
2308 |= (MASK_SVINTO | MASK_ALIGN_BY_32
2309 | MASK_STACK_ALIGN | MASK_CONST_ALIGN
2310 | MASK_DATA_ALIGN);
0b85d816
HPN
2311
2312 /* Note that we do not add new flags when it can be completely
2313 described with a macro that uses -mcpu=X. So
2314 TARGET_HAS_MUL_INSNS is (cris_cpu_version >= CRIS_CPU_NG). */
2315 }
2316
2317 if (cris_tune_str)
2318 {
2319 int cris_tune
2320 = (*cris_tune_str == 'v' ? atoi (cris_tune_str + 1) : -1);
2321
2322 if (strcmp ("etrax4", cris_tune_str) == 0)
2323 cris_tune = 3;
2324
2325 if (strcmp ("svinto", cris_tune_str) == 0
2326 || strcmp ("etrax100", cris_tune_str) == 0)
2327 cris_tune = 8;
2328
2329 if (strcmp ("ng", cris_tune_str) == 0
2330 || strcmp ("etrax100lx", cris_tune_str) == 0)
2331 cris_tune = 10;
2332
c31500c2 2333 if (cris_tune < 0 || cris_tune > 32)
31aa664a 2334 error ("unknown CRIS cpu version specification in %<-mtune=%>: %s",
0b85d816
HPN
2335 cris_tune_str);
2336
2337 if (cris_tune >= CRIS_CPU_SVINTO)
2338 /* We have currently nothing more to tune than alignment for
2339 memory accesses. */
2340 target_flags
2a186d97
HPN
2341 |= (MASK_STACK_ALIGN | MASK_CONST_ALIGN
2342 | MASK_DATA_ALIGN | MASK_ALIGN_BY_32);
0b85d816
HPN
2343 }
2344
2345 if (flag_pic)
2346 {
2347 /* Use error rather than warning, so invalid use is easily
2348 detectable. Still change to the values we expect, to avoid
2349 further errors. */
d0780379
HPN
2350 error ("%<-fPIC%> and %<-fpic%> are not supported on this target");
2351 flag_pic = 0;
0b85d816
HPN
2352 }
2353
0b85d816
HPN
2354 /* Set the per-function-data initializer. */
2355 init_machine_status = cris_init_machine_status;
2356}
2357
eb0424da 2358/* The TARGET_ASM_OUTPUT_MI_THUNK worker. */
0b85d816 2359
c590b625 2360static void
6640377c
SB
2361cris_asm_output_mi_thunk (FILE *stream,
2362 tree thunkdecl ATTRIBUTE_UNUSED,
2363 HOST_WIDE_INT delta,
2364 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
2365 tree funcdecl)
0b85d816 2366{
f7430263
MF
2367 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunkdecl));
2368
2369 assemble_start_function (thunkdecl, fnname);
097f98d4
HPN
2370 /* Make sure unwind info is emitted for the thunk if needed. */
2371 final_start_function (emit_barrier (), stream, 1);
2372
0b85d816 2373 if (delta > 0)
4a0a75dd
KG
2374 fprintf (stream, "\tadd%s " HOST_WIDE_INT_PRINT_DEC ",$%s\n",
2375 ADDITIVE_SIZE_MODIFIER (delta), delta,
2376 reg_names[CRIS_FIRST_ARG_REG]);
0b85d816 2377 else if (delta < 0)
4a0a75dd
KG
2378 fprintf (stream, "\tsub%s " HOST_WIDE_INT_PRINT_DEC ",$%s\n",
2379 ADDITIVE_SIZE_MODIFIER (-delta), -delta,
2380 reg_names[CRIS_FIRST_ARG_REG]);
0b85d816 2381
d0780379
HPN
2382 fprintf (stream, "\tjump ");
2383 assemble_name (stream, XSTR (XEXP (DECL_RTL (funcdecl), 0), 0));
2384 fprintf (stream, "\n");
097f98d4
HPN
2385
2386 final_end_function ();
f7430263 2387 assemble_end_function (thunkdecl, fnname);
0b85d816
HPN
2388}
2389
15883505 2390/* Boilerplate emitted at start of file.
1bc7c5b6
ZW
2391
2392 NO_APP *only at file start* means faster assembly. It also means
2393 comments are not allowed. In some cases comments will be output
0df965d7 2394 for debugging purposes. Make sure they are allowed then. */
1bc7c5b6 2395static void
6640377c 2396cris_file_start (void)
1bc7c5b6
ZW
2397{
2398 /* These expressions can vary at run time, so we cannot put
2399 them into TARGET_INITIALIZER. */
38f8b050 2400 targetm.asm_file_start_app_off = !(TARGET_PDEBUG || flag_print_asm_name);
1bc7c5b6
ZW
2401
2402 default_file_start ();
2403}
2404
c15c90bb
ZW
2405/* Rename the function calls for integer multiply and divide. */
2406static void
30ee56e1 2407cris_init_libfuncs (void)
c15c90bb
ZW
2408{
2409 set_optab_libfunc (smul_optab, SImode, "__Mul");
2410 set_optab_libfunc (sdiv_optab, SImode, "__Div");
2411 set_optab_libfunc (udiv_optab, SImode, "__Udiv");
2412 set_optab_libfunc (smod_optab, SImode, "__Mod");
2413 set_optab_libfunc (umod_optab, SImode, "__Umod");
dec4306f
HPN
2414
2415 /* Atomic data being unaligned is unfortunately a reality.
2416 Deal with it. */
2417 if (TARGET_ATOMICS_MAY_CALL_LIBFUNCS)
2418 {
2419 set_optab_libfunc (sync_compare_and_swap_optab, SImode,
2420 "__cris_atcmpxchgr32");
2421 set_optab_libfunc (sync_compare_and_swap_optab, HImode,
2422 "__cris_atcmpxchgr16");
2423 }
c15c90bb
ZW
2424}
2425
0b85d816
HPN
2426/* The INIT_EXPANDERS worker sets the per-function-data initializer and
2427 mark functions. */
2428
2429void
6640377c 2430cris_init_expanders (void)
0b85d816
HPN
2431{
2432 /* Nothing here at the moment. */
2433}
2434
2435/* Zero initialization is OK for all current fields. */
2436
e2500fed 2437static struct machine_function *
6640377c 2438cris_init_machine_status (void)
0b85d816 2439{
766090c2 2440 return ggc_cleared_alloc<machine_function> ();
0b85d816
HPN
2441}
2442
2443/* Split a 2 word move (DI or presumably DF) into component parts.
e53b6e56 2444 Originally a copy of gen_split_move_double in m32r.cc. */
0b85d816
HPN
2445
2446rtx
6640377c 2447cris_split_movdx (rtx *operands)
0b85d816 2448{
ef4bddc2 2449 machine_mode mode = GET_MODE (operands[0]);
0b85d816
HPN
2450 rtx dest = operands[0];
2451 rtx src = operands[1];
2452 rtx val;
2453
3d556836
HPN
2454 /* We used to have to handle (SUBREG (MEM)) here, but that should no
2455 longer happen; after reload there are no SUBREGs any more, and we're
2456 only called after reload. */
b6c34129 2457 CRIS_ASSERT (GET_CODE (dest) != SUBREG && GET_CODE (src) != SUBREG);
0b85d816
HPN
2458
2459 start_sequence ();
991c42ac 2460 if (REG_P (dest))
0b85d816
HPN
2461 {
2462 int dregno = REGNO (dest);
2463
2464 /* Reg-to-reg copy. */
991c42ac 2465 if (REG_P (src))
0b85d816
HPN
2466 {
2467 int sregno = REGNO (src);
2468
2469 int reverse = (dregno == sregno + 1);
2470
2471 /* We normally copy the low-numbered register first. However, if
2472 the first register operand 0 is the same as the second register of
2473 operand 1, we must copy in the opposite order. */
fb062a8b
HPN
2474 emit_move_insn (operand_subword (dest, reverse, TRUE, mode),
2475 operand_subword (src, reverse, TRUE, mode));
0b85d816 2476
fb062a8b
HPN
2477 emit_move_insn (operand_subword (dest, !reverse, TRUE, mode),
2478 operand_subword (src, !reverse, TRUE, mode));
0b85d816
HPN
2479 }
2480 /* Constant-to-reg copy. */
991c42ac 2481 else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE)
0b85d816
HPN
2482 {
2483 rtx words[2];
2484 split_double (src, &words[0], &words[1]);
fb062a8b 2485 emit_move_insn (operand_subword (dest, 0, TRUE, mode), words[0]);
0b85d816 2486
fb062a8b 2487 emit_move_insn (operand_subword (dest, 1, TRUE, mode), words[1]);
0b85d816
HPN
2488 }
2489 /* Mem-to-reg copy. */
991c42ac 2490 else if (MEM_P (src))
0b85d816
HPN
2491 {
2492 /* If the high-address word is used in the address, we must load it
2493 last. Otherwise, load it first. */
2494 rtx addr = XEXP (src, 0);
c9bd6bcd 2495 int reverse = (refers_to_regno_p (dregno, addr) != 0);
0b85d816 2496
1ae58c30 2497 /* The original code implies that we can't do
0b85d816
HPN
2498 move.x [rN+],rM move.x [rN],rM+1
2499 when rN is dead, because of REG_NOTES damage. That is
2500 consistent with what I've seen, so don't try it.
2501
2502 We have two different cases here; if the addr is POST_INC,
2503 just pass it through, otherwise add constants. */
2504
2505 if (GET_CODE (addr) == POST_INC)
2506 {
752b602f
HPN
2507 rtx mem;
2508 rtx insn;
2509
2510 /* Whenever we emit insns with post-incremented
2511 addresses ourselves, we must add a post-inc note
2512 manually. */
2513 mem = change_address (src, SImode, addr);
fb062a8b
HPN
2514 insn = emit_move_insn (operand_subword (dest, 0, TRUE, mode),
2515 mem);
752b602f
HPN
2516 if (GET_CODE (XEXP (mem, 0)) == POST_INC)
2517 REG_NOTES (insn)
2518 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
2519 REG_NOTES (insn));
2520
c31500c2 2521 mem = copy_rtx (mem);
fb062a8b 2522 insn = emit_move_insn (operand_subword (dest, 1, TRUE, mode), mem);
752b602f
HPN
2523 if (GET_CODE (XEXP (mem, 0)) == POST_INC)
2524 REG_NOTES (insn)
2525 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
2526 REG_NOTES (insn));
0b85d816
HPN
2527 }
2528 else
2529 {
2530 /* Make sure we don't get any other addresses with
2531 embedded postincrements. They should be stopped in
2532 GO_IF_LEGITIMATE_ADDRESS, but we're here for your
2533 safety. */
2534 if (side_effects_p (addr))
c725bd79 2535 fatal_insn ("unexpected side-effects in address", addr);
0b85d816 2536
fb062a8b
HPN
2537 emit_move_insn (operand_subword (dest, reverse, TRUE, mode),
2538 change_address
2539 (src, SImode,
2540 plus_constant (Pmode, addr,
2541 reverse * UNITS_PER_WORD)));
2542 emit_move_insn (operand_subword (dest, ! reverse, TRUE, mode),
2543 change_address
2544 (src, SImode,
2545 plus_constant (Pmode, addr,
2546 (! reverse) *
2547 UNITS_PER_WORD)));
0b85d816
HPN
2548 }
2549 }
2550 else
d8a07487 2551 internal_error ("unknown src");
0b85d816
HPN
2552 }
2553 /* Reg-to-mem copy or clear mem. */
991c42ac
JBG
2554 else if (MEM_P (dest)
2555 && (REG_P (src)
0b85d816
HPN
2556 || src == const0_rtx
2557 || src == CONST0_RTX (DFmode)))
2558 {
2559 rtx addr = XEXP (dest, 0);
2560
2561 if (GET_CODE (addr) == POST_INC)
2562 {
752b602f
HPN
2563 rtx mem;
2564 rtx insn;
991c42ac 2565
752b602f
HPN
2566 /* Whenever we emit insns with post-incremented addresses
2567 ourselves, we must add a post-inc note manually. */
2568 mem = change_address (dest, SImode, addr);
fb062a8b 2569 insn = emit_move_insn (mem, operand_subword (src, 0, TRUE, mode));
752b602f
HPN
2570 if (GET_CODE (XEXP (mem, 0)) == POST_INC)
2571 REG_NOTES (insn)
2572 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
2573 REG_NOTES (insn));
2574
c31500c2 2575 mem = copy_rtx (mem);
fb062a8b 2576 insn = emit_move_insn (mem, operand_subword (src, 1, TRUE, mode));
752b602f
HPN
2577 if (GET_CODE (XEXP (mem, 0)) == POST_INC)
2578 REG_NOTES (insn)
2579 = alloc_EXPR_LIST (REG_INC, XEXP (XEXP (mem, 0), 0),
2580 REG_NOTES (insn));
0b85d816
HPN
2581 }
2582 else
2583 {
2584 /* Make sure we don't get any other addresses with embedded
2585 postincrements. They should be stopped in
2586 GO_IF_LEGITIMATE_ADDRESS, but we're here for your safety. */
2587 if (side_effects_p (addr))
c725bd79 2588 fatal_insn ("unexpected side-effects in address", addr);
0b85d816 2589
fb062a8b
HPN
2590 emit_move_insn (change_address (dest, SImode, addr),
2591 operand_subword (src, 0, TRUE, mode));
0b85d816 2592
fb062a8b
HPN
2593 emit_move_insn (change_address (dest, SImode,
2594 plus_constant (Pmode, addr,
2595 UNITS_PER_WORD)),
2596 operand_subword (src, 1, TRUE, mode));
0b85d816
HPN
2597 }
2598 }
2599
2600 else
d8a07487 2601 internal_error ("unknown dest");
0b85d816 2602
2f937369 2603 val = get_insns ();
0b85d816
HPN
2604 end_sequence ();
2605 return val;
2606}
2607
cfaf5204
HPN
2608/* Try to change a comparison against a constant to be against zero, and
2609 an unsigned compare against zero to be an equality test. Beware:
2610 only valid for compares of integer-type operands. Also, note that we
2611 don't use operand 0 at the moment. */
2612
2613void
2614cris_reduce_compare (rtx *relp, rtx *, rtx *op1p)
2615{
2616 rtx op1 = *op1p;
2617 rtx_code code = GET_CODE (*relp);
2618
2619 /* Code lifted mostly from emit_store_flag_1. */
2620 switch (code)
2621 {
2622 case LT:
2623 if (op1 == const1_rtx)
2624 code = LE;
2625 break;
2626 case LE:
2627 if (op1 == constm1_rtx)
2628 code = LT;
2629 break;
2630 case GE:
2631 if (op1 == const1_rtx)
2632 code = GT;
2633 break;
2634 case GT:
2635 if (op1 == constm1_rtx)
2636 code = GE;
2637 break;
2638 case GEU:
2639 if (op1 == const1_rtx)
2640 code = NE;
2641 break;
2642 case LTU:
2643 if (op1 == const1_rtx)
2644 code = EQ;
2645 break;
2646 case GTU:
2647 if (op1 == const0_rtx)
2648 code = NE;
2649 break;
2650 case LEU:
2651 if (op1 == const0_rtx)
2652 code = EQ;
2653 break;
2654 default:
2655 break;
2656 }
2657
2658 if (code != GET_CODE (*relp))
2659 {
2660 *op1p = const0_rtx;
2661 PUT_CODE (*relp, code);
2662 }
2663}
2664
d29b4b1b
HPN
2665/* The expander for the prologue pattern name. */
2666
2667void
2668cris_expand_prologue (void)
2669{
2670 int regno;
2671 int size = get_frame_size ();
2672 /* Shorten the used name for readability. */
38173d38 2673 int cfoa_size = crtl->outgoing_args_size;
d29b4b1b
HPN
2674 int last_movem_reg = -1;
2675 int framesize = 0;
2676 rtx mem, insn;
2677 int return_address_on_stack = cris_return_address_on_stack ();
d29b4b1b 2678 int n_movem_regs = 0;
38173d38 2679 int pretend = crtl->args.pretend_args_size;
d29b4b1b
HPN
2680
2681 /* Don't do anything if no prologues or epilogues are wanted. */
2682 if (!TARGET_PROLOGUE_EPILOGUE)
2683 return;
2684
b6c34129 2685 CRIS_ASSERT (size >= 0);
d29b4b1b
HPN
2686
2687 /* Align the size to what's best for the CPU model. */
2688 if (TARGET_STACK_ALIGN)
2689 size = TARGET_ALIGN_BY_32 ? (size + 3) & ~3 : (size + 1) & ~1;
2690
2691 if (pretend)
2692 {
2693 /* See also cris_setup_incoming_varargs where
2694 cfun->machine->stdarg_regs is set. There are other setters of
38173d38 2695 crtl->args.pretend_args_size than stdarg handling, like
d29b4b1b
HPN
2696 for an argument passed with parts in R13 and stack. We must
2697 not store R13 into the pretend-area for that case, as GCC does
2698 that itself. "Our" store would be marked as redundant and GCC
2699 will attempt to remove it, which will then be flagged as an
2700 internal error; trying to remove a frame-related insn. */
2701 int stdarg_regs = cfun->machine->stdarg_regs;
2702
2703 framesize += pretend;
2704
2705 for (regno = CRIS_FIRST_ARG_REG + CRIS_MAX_ARGS_IN_REGS - 1;
2706 stdarg_regs > 0;
2707 regno--, pretend -= 4, stdarg_regs--)
2708 {
fb062a8b 2709 insn = emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (-4)));
d29b4b1b
HPN
2710 /* FIXME: When dwarf2 frame output and unless asynchronous
2711 exceptions, make dwarf2 bundle together all stack
2712 adjustments like it does for registers between stack
2713 adjustments. */
2714 RTX_FRAME_RELATED_P (insn) = 1;
2715
2716 mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
2717 set_mem_alias_set (mem, get_varargs_alias_set ());
e5561c83 2718 insn = emit_move_insn (mem, gen_raw_REG (SImode, regno));
d29b4b1b
HPN
2719
2720 /* Note the absence of RTX_FRAME_RELATED_P on the above insn:
2721 the value isn't restored, so we don't want to tell dwarf2
2722 that it's been stored to stack, else EH handling info would
2723 get confused. */
2724 }
2725
38173d38 2726 /* For other setters of crtl->args.pretend_args_size, we
d29b4b1b
HPN
2727 just adjust the stack by leaving the remaining size in
2728 "pretend", handled below. */
2729 }
2730
2731 /* Save SRP if not a leaf function. */
2732 if (return_address_on_stack)
2733 {
fb062a8b
HPN
2734 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
2735 GEN_INT (-4 - pretend)));
d29b4b1b
HPN
2736 pretend = 0;
2737 RTX_FRAME_RELATED_P (insn) = 1;
2738
2739 mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
2740 set_mem_alias_set (mem, get_frame_alias_set ());
e5561c83 2741 insn = emit_move_insn (mem, gen_raw_REG (SImode, CRIS_SRP_REGNUM));
d29b4b1b
HPN
2742 RTX_FRAME_RELATED_P (insn) = 1;
2743 framesize += 4;
2744 }
2745
2746 /* Set up the frame pointer, if needed. */
2747 if (frame_pointer_needed)
2748 {
fb062a8b
HPN
2749 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
2750 GEN_INT (-4 - pretend)));
d29b4b1b
HPN
2751 pretend = 0;
2752 RTX_FRAME_RELATED_P (insn) = 1;
2753
2754 mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
2755 set_mem_alias_set (mem, get_frame_alias_set ());
aa27696b 2756 insn = emit_move_insn (mem, hard_frame_pointer_rtx);
d29b4b1b
HPN
2757 RTX_FRAME_RELATED_P (insn) = 1;
2758
aa27696b 2759 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
d29b4b1b
HPN
2760 RTX_FRAME_RELATED_P (insn) = 1;
2761
2762 framesize += 4;
2763 }
2764
2765 /* Between frame-pointer and saved registers lie the area for local
2766 variables. If we get here with "pretended" size remaining, count
2767 it into the general stack size. */
2768 size += pretend;
2769
2770 /* Get a contiguous sequence of registers, starting with R0, that need
2771 to be saved. */
2772 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2773 {
d0780379 2774 if (cris_reg_saved_in_regsave_area (regno))
d29b4b1b
HPN
2775 {
2776 n_movem_regs++;
2777
2778 /* Check if movem may be used for registers so far. */
2779 if (regno == last_movem_reg + 1)
2780 /* Yes, update next expected register. */
2781 last_movem_reg = regno;
2782 else
2783 {
2784 /* We cannot use movem for all registers. We have to flush
2785 any movem:ed registers we got so far. */
2786 if (last_movem_reg != -1)
2787 {
2788 int n_saved
2789 = (n_movem_regs == 1) ? 1 : last_movem_reg + 1;
2790
2791 /* It is a win to use a side-effect assignment for
2792 64 <= size <= 128. But side-effect on movem was
2793 not usable for CRIS v0..3. Also only do it if
2794 side-effects insns are allowed. */
2795 if ((last_movem_reg + 1) * 4 + size >= 64
2796 && (last_movem_reg + 1) * 4 + size <= 128
fb062a8b
HPN
2797 && cris_cpu_version >= CRIS_CPU_SVINTO
2798 /* Don't use side-effect assignment for a single
2799 move. */
2800 && n_saved > 1
d29b4b1b
HPN
2801 && TARGET_SIDE_EFFECT_PREFIXES)
2802 {
2803 mem
2804 = gen_rtx_MEM (SImode,
0a81f074 2805 plus_constant (Pmode, stack_pointer_rtx,
d29b4b1b
HPN
2806 -(n_saved * 4 + size)));
2807 set_mem_alias_set (mem, get_frame_alias_set ());
2808 insn
2809 = cris_emit_movem_store (mem, GEN_INT (n_saved),
2810 -(n_saved * 4 + size),
2811 true);
2812 }
2813 else
2814 {
2815 insn
fb062a8b
HPN
2816 = emit_insn (gen_add2_insn (stack_pointer_rtx,
2817 GEN_INT (-(n_saved * 4
2818 + size))));
d29b4b1b
HPN
2819 RTX_FRAME_RELATED_P (insn) = 1;
2820
2821 mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
2822 set_mem_alias_set (mem, get_frame_alias_set ());
2823 insn = cris_emit_movem_store (mem, GEN_INT (n_saved),
2824 0, true);
2825 }
2826
2827 framesize += n_saved * 4 + size;
2828 last_movem_reg = -1;
2829 size = 0;
2830 }
2831
fb062a8b
HPN
2832 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
2833 GEN_INT (-4 - size)));
d29b4b1b
HPN
2834 RTX_FRAME_RELATED_P (insn) = 1;
2835
2836 mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
2837 set_mem_alias_set (mem, get_frame_alias_set ());
e5561c83 2838 insn = emit_move_insn (mem, gen_raw_REG (SImode, regno));
d29b4b1b
HPN
2839 RTX_FRAME_RELATED_P (insn) = 1;
2840
2841 framesize += 4 + size;
2842 size = 0;
2843 }
2844 }
2845 }
2846
2847 /* Check after, if we could movem all registers. This is the normal case. */
2848 if (last_movem_reg != -1)
2849 {
2850 int n_saved
2851 = (n_movem_regs == 1) ? 1 : last_movem_reg + 1;
2852
2853 /* Side-effect on movem was not usable for CRIS v0..3. Also only
2854 do it if side-effects insns are allowed. */
2855 if ((last_movem_reg + 1) * 4 + size >= 64
2856 && (last_movem_reg + 1) * 4 + size <= 128
fb062a8b
HPN
2857 && cris_cpu_version >= CRIS_CPU_SVINTO
2858 /* Don't use side-effect assignment for a single move. */
2859 && n_saved > 1
d29b4b1b
HPN
2860 && TARGET_SIDE_EFFECT_PREFIXES)
2861 {
2862 mem
2863 = gen_rtx_MEM (SImode,
0a81f074 2864 plus_constant (Pmode, stack_pointer_rtx,
d29b4b1b
HPN
2865 -(n_saved * 4 + size)));
2866 set_mem_alias_set (mem, get_frame_alias_set ());
2867 insn = cris_emit_movem_store (mem, GEN_INT (n_saved),
2868 -(n_saved * 4 + size), true);
2869 }
2870 else
2871 {
fb062a8b
HPN
2872 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
2873 GEN_INT (-(n_saved * 4 + size))));
d29b4b1b
HPN
2874 RTX_FRAME_RELATED_P (insn) = 1;
2875
2876 mem = gen_rtx_MEM (SImode, stack_pointer_rtx);
2877 set_mem_alias_set (mem, get_frame_alias_set ());
2878 insn = cris_emit_movem_store (mem, GEN_INT (n_saved), 0, true);
2879 }
2880
2881 framesize += n_saved * 4 + size;
2882 /* We have to put outgoing argument space after regs. */
2883 if (cfoa_size)
2884 {
fb062a8b
HPN
2885 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
2886 GEN_INT (-cfoa_size)));
d29b4b1b
HPN
2887 RTX_FRAME_RELATED_P (insn) = 1;
2888 framesize += cfoa_size;
2889 }
2890 }
2891 else if ((size + cfoa_size) > 0)
2892 {
fb062a8b
HPN
2893 insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
2894 GEN_INT (-(cfoa_size + size))));
d29b4b1b
HPN
2895 RTX_FRAME_RELATED_P (insn) = 1;
2896 framesize += size + cfoa_size;
2897 }
2898
9e0d8a37
HPN
2899 /* FIXME: -mmax-stackframe=SIZE is obsoleted; use -Wstack-usage=SIZE
2900 instead. Make it an alias? */
d29b4b1b 2901 if (cris_max_stackframe && framesize > cris_max_stackframe)
d4ee4d25 2902 warning (0, "stackframe too big: %d bytes", framesize);
9e0d8a37
HPN
2903
2904 if (flag_stack_usage_info)
2905 current_function_static_stack_size = framesize;
d29b4b1b
HPN
2906}
2907
04539954
HPN
2908/* The expander for the epilogue pattern. */
2909
2910void
2911cris_expand_epilogue (void)
2912{
2913 int regno;
2914 int size = get_frame_size ();
2915 int last_movem_reg = -1;
38173d38
JH
2916 int argspace_offset = crtl->outgoing_args_size;
2917 int pretend = crtl->args.pretend_args_size;
04539954
HPN
2918 rtx mem;
2919 bool return_address_on_stack = cris_return_address_on_stack ();
2920 /* A reference may have been optimized out
2921 (like the abort () in fde_split in unwind-dw2-fde.c, at least 3.2.1)
2922 so check that it's still used. */
04539954
HPN
2923 int n_movem_regs = 0;
2924
2925 if (!TARGET_PROLOGUE_EPILOGUE)
2926 return;
2927
2928 /* Align byte count of stack frame. */
2929 if (TARGET_STACK_ALIGN)
2930 size = TARGET_ALIGN_BY_32 ? (size + 3) & ~3 : (size + 1) & ~1;
2931
2932 /* Check how many saved regs we can movem. They start at r0 and must
2933 be contiguous. */
2934 for (regno = 0;
2935 regno < FIRST_PSEUDO_REGISTER;
2936 regno++)
d0780379 2937 if (cris_reg_saved_in_regsave_area (regno))
04539954
HPN
2938 {
2939 n_movem_regs++;
2940
2941 if (regno == last_movem_reg + 1)
2942 last_movem_reg = regno;
2943 else
2944 break;
2945 }
2946
2947 /* If there was only one register that really needed to be saved
2948 through movem, don't use movem. */
2949 if (n_movem_regs == 1)
2950 last_movem_reg = -1;
2951
2952 /* Now emit "normal" move insns for all regs higher than the movem
2953 regs. */
2954 for (regno = FIRST_PSEUDO_REGISTER - 1;
2955 regno > last_movem_reg;
2956 regno--)
d0780379 2957 if (cris_reg_saved_in_regsave_area (regno))
04539954 2958 {
752b602f
HPN
2959 rtx insn;
2960
04539954
HPN
2961 if (argspace_offset)
2962 {
2963 /* There is an area for outgoing parameters located before
2964 the saved registers. We have to adjust for that. */
fb062a8b
HPN
2965 emit_insn (gen_add2_insn (stack_pointer_rtx,
2966 GEN_INT (argspace_offset)));
04539954
HPN
2967 /* Make sure we only do this once. */
2968 argspace_offset = 0;
2969 }
2970
2971 mem = gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode,
2972 stack_pointer_rtx));
2973 set_mem_alias_set (mem, get_frame_alias_set ());
e5561c83 2974 insn = emit_move_insn (gen_raw_REG (SImode, regno), mem);
752b602f
HPN
2975
2976 /* Whenever we emit insns with post-incremented addresses
2977 ourselves, we must add a post-inc note manually. */
2978 REG_NOTES (insn)
2979 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
04539954
HPN
2980 }
2981
2982 /* If we have any movem-restore, do it now. */
2983 if (last_movem_reg != -1)
2984 {
752b602f
HPN
2985 rtx insn;
2986
04539954
HPN
2987 if (argspace_offset)
2988 {
fb062a8b 2989 emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (argspace_offset)));
04539954
HPN
2990 argspace_offset = 0;
2991 }
2992
2993 mem = gen_rtx_MEM (SImode,
2994 gen_rtx_POST_INC (SImode, stack_pointer_rtx));
2995 set_mem_alias_set (mem, get_frame_alias_set ());
752b602f 2996 insn
fb062a8b 2997 = emit_insn (cris_gen_movem_load (mem, GEN_INT (last_movem_reg + 1)));
752b602f
HPN
2998 /* Whenever we emit insns with post-incremented addresses
2999 ourselves, we must add a post-inc note manually. */
3000 if (side_effects_p (PATTERN (insn)))
3001 REG_NOTES (insn)
3002 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
04539954
HPN
3003 }
3004
3005 /* If we don't clobber all of the allocated stack area (we've already
3006 deallocated saved registers), GCC might want to schedule loads from
3007 the stack to *after* the stack-pointer restore, which introduces an
3008 interrupt race condition. This happened for the initial-value
3009 SRP-restore for g++.dg/eh/registers1.C (noticed by inspection of
3010 other failure for that test). It also happened for the stack slot
3011 for the return value in (one version of)
3012 linux/fs/dcache.c:__d_lookup, at least with "-O2
3013 -fno-omit-frame-pointer". */
3014
3015 /* Restore frame pointer if necessary. */
3016 if (frame_pointer_needed)
3017 {
752b602f
HPN
3018 rtx insn;
3019
04539954
HPN
3020 emit_insn (gen_cris_frame_deallocated_barrier ());
3021
aa27696b 3022 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
04539954
HPN
3023 mem = gen_rtx_MEM (SImode, gen_rtx_POST_INC (SImode,
3024 stack_pointer_rtx));
3025 set_mem_alias_set (mem, get_frame_alias_set ());
aa27696b 3026 insn = emit_move_insn (hard_frame_pointer_rtx, mem);
752b602f
HPN
3027
3028 /* Whenever we emit insns with post-incremented addresses
3029 ourselves, we must add a post-inc note manually. */
3030 REG_NOTES (insn)
3031 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
04539954
HPN
3032 }
3033 else if ((size + argspace_offset) != 0)
3034 {
3035 emit_insn (gen_cris_frame_deallocated_barrier ());
3036
3037 /* If there was no frame-pointer to restore sp from, we must
3038 explicitly deallocate local variables. */
3039
3040 /* Handle space for outgoing parameters that hasn't been handled
3041 yet. */
3042 size += argspace_offset;
3043
fb062a8b 3044 emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (size)));
04539954
HPN
3045 }
3046
3047 /* If this function has no pushed register parameters
3048 (stdargs/varargs), and if it is not a leaf function, then we have
3049 the return address on the stack. */
3050 if (return_address_on_stack && pretend == 0)
3051 {
d0780379 3052 if (crtl->calls_eh_return)
04539954
HPN
3053 {
3054 rtx mem;
752b602f 3055 rtx insn;
e5561c83 3056 rtx srpreg = gen_raw_REG (SImode, CRIS_SRP_REGNUM);
04539954
HPN
3057 mem = gen_rtx_MEM (SImode,
3058 gen_rtx_POST_INC (SImode,
3059 stack_pointer_rtx));
3060 set_mem_alias_set (mem, get_frame_alias_set ());
752b602f
HPN
3061 insn = emit_move_insn (srpreg, mem);
3062
3063 /* Whenever we emit insns with post-incremented addresses
3064 ourselves, we must add a post-inc note manually. */
3065 REG_NOTES (insn)
3066 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
04539954 3067
e3b5732b 3068 if (crtl->calls_eh_return)
fb062a8b
HPN
3069 emit_insn (gen_add2_insn (stack_pointer_rtx,
3070 gen_raw_REG (SImode, CRIS_STACKADJ_REG)));
04539954
HPN
3071 cris_expand_return (false);
3072 }
3073 else
3074 cris_expand_return (true);
3075
3076 return;
3077 }
3078
3079 /* If we pushed some register parameters, then adjust the stack for
3080 them. */
3081 if (pretend != 0)
3082 {
3083 /* If SRP is stored on the way, we need to restore it first. */
3084 if (return_address_on_stack)
3085 {
3086 rtx mem;
e5561c83 3087 rtx srpreg = gen_raw_REG (SImode, CRIS_SRP_REGNUM);
752b602f
HPN
3088 rtx insn;
3089
04539954
HPN
3090 mem = gen_rtx_MEM (SImode,
3091 gen_rtx_POST_INC (SImode,
3092 stack_pointer_rtx));
3093 set_mem_alias_set (mem, get_frame_alias_set ());
752b602f
HPN
3094 insn = emit_move_insn (srpreg, mem);
3095
3096 /* Whenever we emit insns with post-incremented addresses
3097 ourselves, we must add a post-inc note manually. */
3098 REG_NOTES (insn)
3099 = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
04539954
HPN
3100 }
3101
fb062a8b 3102 emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (pretend)));
04539954
HPN
3103 }
3104
3105 /* Perform the "physical" unwinding that the EH machinery calculated. */
e3b5732b 3106 if (crtl->calls_eh_return)
fb062a8b
HPN
3107 emit_insn (gen_add2_insn (stack_pointer_rtx,
3108 gen_raw_REG (SImode, CRIS_STACKADJ_REG)));
04539954
HPN
3109 cris_expand_return (false);
3110}
3111
3112/* Worker function for generating movem from mem for load_multiple. */
3113
3114rtx
fb062a8b 3115cris_gen_movem_load (rtx src, rtx nregs_rtx)
04539954
HPN
3116{
3117 int nregs = INTVAL (nregs_rtx);
3118 rtvec vec;
3119 int eltno = 1;
3120 int i;
d29b4b1b 3121 rtx srcreg = XEXP (src, 0);
04539954
HPN
3122 unsigned int regno = nregs - 1;
3123 int regno_inc = -1;
3124
3125 if (GET_CODE (srcreg) == POST_INC)
3126 srcreg = XEXP (srcreg, 0);
3127
b6c34129 3128 CRIS_ASSERT (REG_P (srcreg));
04539954 3129
d0780379 3130 /* Don't use movem for just one insn. The insns are equivalent. */
04539954 3131 if (nregs == 1)
d29b4b1b 3132 return gen_movsi (gen_rtx_REG (SImode, 0), src);
04539954 3133
fb062a8b 3134 vec = rtvec_alloc (nregs + (GET_CODE (XEXP (src, 0)) == POST_INC));
04539954 3135
d29b4b1b 3136 if (GET_CODE (XEXP (src, 0)) == POST_INC)
04539954 3137 {
fb062a8b 3138 RTVEC_ELT (vec, 1)
f7df4a84 3139 = gen_rtx_SET (srcreg, plus_constant (Pmode, srcreg, nregs * 4));
04539954
HPN
3140 eltno++;
3141 }
3142
d29b4b1b 3143 src = replace_equiv_address (src, srcreg);
fb062a8b 3144 RTVEC_ELT (vec, 0)
f7df4a84 3145 = gen_rtx_SET (gen_rtx_REG (SImode, regno), src);
d29b4b1b
HPN
3146 regno += regno_inc;
3147
04539954
HPN
3148 for (i = 1; i < nregs; i++, eltno++)
3149 {
fb062a8b 3150 RTVEC_ELT (vec, eltno)
f7df4a84 3151 = gen_rtx_SET (gen_rtx_REG (SImode, regno),
04539954
HPN
3152 adjust_address_nv (src, SImode, i * 4));
3153 regno += regno_inc;
3154 }
3155
3156 return gen_rtx_PARALLEL (VOIDmode, vec);
3157}
3158
fb062a8b
HPN
3159/* Convenience function for CRIS-local use of emit_insn, wrapping the
3160 argument in a parallel with a clobber of CRIS_CC0_REGNUM before
3161 passing on to emit_insn. */
3162
3163rtx_insn *
3164cris_emit_insn (rtx x)
3165{
3166 rtvec vec = rtvec_alloc (2);
3167
3168 RTVEC_ELT (vec, 0) = x;
3169 RTVEC_ELT (vec, 1)
3170 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CRIS_CC0_REGNUM));
3171
3172 return emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
3173}
3174
d29b4b1b
HPN
3175/* Worker function for generating movem to mem. If FRAME_RELATED, notes
3176 are added that the dwarf2 machinery understands. */
3177
3178rtx
3179cris_emit_movem_store (rtx dest, rtx nregs_rtx, int increment,
3180 bool frame_related)
3181{
3182 int nregs = INTVAL (nregs_rtx);
3183 rtvec vec;
3184 int eltno = 1;
3185 int i;
3186 rtx insn;
3187 rtx destreg = XEXP (dest, 0);
3188 unsigned int regno = nregs - 1;
3189 int regno_inc = -1;
3190
3191 if (GET_CODE (destreg) == POST_INC)
3192 increment += nregs * 4;
3193
3194 if (GET_CODE (destreg) == POST_INC || GET_CODE (destreg) == PLUS)
3195 destreg = XEXP (destreg, 0);
3196
b6c34129 3197 CRIS_ASSERT (REG_P (destreg));
d29b4b1b 3198
d0780379 3199 /* Don't use movem for just one insn. The insns are equivalent. */
d29b4b1b
HPN
3200 if (nregs == 1)
3201 {
d29b4b1b
HPN
3202 if (increment == 0)
3203 {
fb062a8b 3204 insn = emit_move_insn (dest, gen_rtx_REG (SImode, 0));
d29b4b1b
HPN
3205 if (frame_related)
3206 RTX_FRAME_RELATED_P (insn) = 1;
3207 return insn;
3208 }
3209
3210 /* If there was a request for a side-effect, create the ordinary
3211 parallel. */
fb062a8b 3212 vec = rtvec_alloc (3);
d29b4b1b 3213
fb062a8b 3214 rtx mov = gen_rtx_SET (dest, gen_rtx_REG (SImode, 0));
d29b4b1b 3215 RTVEC_ELT (vec, 0) = mov;
f7df4a84
RS
3216 RTVEC_ELT (vec, 1) = gen_rtx_SET (destreg, plus_constant (Pmode, destreg,
3217 increment));
fb062a8b
HPN
3218 RTVEC_ELT (vec, 2)
3219 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CRIS_CC0_REGNUM));
3220
d29b4b1b
HPN
3221 if (frame_related)
3222 {
3223 RTX_FRAME_RELATED_P (mov) = 1;
3224 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 1)) = 1;
3225 }
3226 }
3227 else
3228 {
3229 vec = rtvec_alloc (nregs + (increment != 0 ? 1 : 0));
3230 RTVEC_ELT (vec, 0)
f7df4a84 3231 = gen_rtx_SET (replace_equiv_address (dest,
0a81f074 3232 plus_constant (Pmode, destreg,
d29b4b1b
HPN
3233 increment)),
3234 gen_rtx_REG (SImode, regno));
3235 regno += regno_inc;
3236
3237 /* The dwarf2 info wants this mark on each component in a parallel
3238 that's part of the prologue (though it's optional on the first
3239 component). */
3240 if (frame_related)
3241 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 0)) = 1;
3242
3243 if (increment != 0)
3244 {
3245 RTVEC_ELT (vec, 1)
f7df4a84
RS
3246 = gen_rtx_SET (destreg, plus_constant (Pmode, destreg,
3247 increment != 0
3248 ? increment : nregs * 4));
d29b4b1b
HPN
3249 eltno++;
3250
3251 if (frame_related)
3252 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, 1)) = 1;
3253
3254 /* Don't call adjust_address_nv on a post-incremented address if
3255 we can help it. */
3256 if (GET_CODE (XEXP (dest, 0)) == POST_INC)
3257 dest = replace_equiv_address (dest, destreg);
3258 }
3259
3260 for (i = 1; i < nregs; i++, eltno++)
3261 {
3262 RTVEC_ELT (vec, eltno)
f7df4a84 3263 = gen_rtx_SET (adjust_address_nv (dest, SImode, i * 4),
d29b4b1b
HPN
3264 gen_rtx_REG (SImode, regno));
3265 if (frame_related)
3266 RTX_FRAME_RELATED_P (RTVEC_ELT (vec, eltno)) = 1;
3267 regno += regno_inc;
3268 }
3269 }
3270
3271 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
3272
e53b6e56 3273 /* Because dwarf2out.cc handles the insns in a parallel as a sequence,
d29b4b1b
HPN
3274 we need to keep the stack adjustment separate, after the
3275 MEM-setters. Else the stack-adjustment in the second component of
3276 the parallel would be mishandled; the offsets for the SETs that
3277 follow it would be wrong. We prepare for this by adding a
3278 REG_FRAME_RELATED_EXPR with the MEM-setting parts in a SEQUENCE
3279 followed by the increment. Note that we have FRAME_RELATED_P on
3280 all the SETs, including the original stack adjustment SET in the
3281 parallel. */
3282 if (frame_related)
3283 {
3284 if (increment != 0)
3285 {
3286 rtx seq = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nregs + 1));
dfc0fb23 3287 XVECEXP (seq, 0, 0) = copy_rtx (XVECEXP (PATTERN (insn), 0, 0));
d29b4b1b 3288 for (i = 1; i < nregs; i++)
dfc0fb23
HPN
3289 XVECEXP (seq, 0, i)
3290 = copy_rtx (XVECEXP (PATTERN (insn), 0, i + 1));
3291 XVECEXP (seq, 0, nregs) = copy_rtx (XVECEXP (PATTERN (insn), 0, 1));
973c3795 3292 add_reg_note (insn, REG_FRAME_RELATED_EXPR, seq);
d29b4b1b
HPN
3293 }
3294
3295 RTX_FRAME_RELATED_P (insn) = 1;
3296 }
3297
3298 return insn;
3299}
3300
7faa3eb8 3301/* Make sure operands are in the right order for an addsi3 insn as
5e41dd6f
HPN
3302 generated by a define_split. Nothing but REG_P as the first
3303 operand is recognized by addsi3 after reload. OPERANDS contains
3304 the operands, with the first at OPERANDS[N] and the second at
3305 OPERANDS[N+1]. */
7faa3eb8
HPN
3306
3307void
3308cris_order_for_addsi3 (rtx *operands, int n)
3309{
5e41dd6f 3310 if (!REG_P (operands[n]))
7faa3eb8
HPN
3311 {
3312 rtx tem = operands[n];
3313 operands[n] = operands[n + 1];
3314 operands[n + 1] = tem;
3315 }
3316}
3317
453bd0f5
HPN
3318/* Use from within code, from e.g. PRINT_OPERAND and
3319 PRINT_OPERAND_ADDRESS. Macros used in output_addr_const need to emit
3320 different things depending on whether code operand or constant is
3321 emitted. */
0b85d816 3322
453bd0f5 3323static void
6640377c 3324cris_output_addr_const (FILE *file, rtx x)
0b85d816 3325{
453bd0f5
HPN
3326 in_code++;
3327 output_addr_const (file, x);
3328 in_code--;
3329}
0b85d816 3330
453bd0f5 3331/* Worker function for ASM_OUTPUT_SYMBOL_REF. */
0b85d816 3332
453bd0f5
HPN
3333void
3334cris_asm_output_symbol_ref (FILE *file, rtx x)
3335{
c00fc5cf 3336 gcc_assert (GET_CODE (x) == SYMBOL_REF);
d0780379 3337 assemble_name (file, XSTR (x, 0));
453bd0f5 3338}
0b85d816 3339
453bd0f5 3340/* Worker function for ASM_OUTPUT_LABEL_REF. */
0b85d816 3341
453bd0f5
HPN
3342void
3343cris_asm_output_label_ref (FILE *file, char *buf)
3344{
d0780379 3345 assemble_name (file, buf);
0b85d816
HPN
3346}
3347
a2fef3a4
KH
3348/* Worker function for TARGET_STRUCT_VALUE_RTX. */
3349
3350static rtx
3351cris_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
3352 int incoming ATTRIBUTE_UNUSED)
3353{
3354 return gen_rtx_REG (Pmode, CRIS_STRUCT_VALUE_REGNUM);
3355}
3356
558d352a
KH
3357/* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
3358
3359static void
d5cc9181 3360cris_setup_incoming_varargs (cumulative_args_t ca_v,
e7056ca4 3361 const function_arg_info &,
558d352a
KH
3362 int *pretend_arg_size,
3363 int second_time)
3364{
d5cc9181
JR
3365 CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
3366
558d352a 3367 if (ca->regs < CRIS_MAX_ARGS_IN_REGS)
558d352a 3368 {
d29b4b1b
HPN
3369 int stdarg_regs = CRIS_MAX_ARGS_IN_REGS - ca->regs;
3370 cfun->machine->stdarg_regs = stdarg_regs;
3371 *pretend_arg_size = stdarg_regs * 4;
558d352a 3372 }
d29b4b1b
HPN
3373
3374 if (TARGET_PDEBUG)
3375 fprintf (asm_out_file,
3376 "\n; VA:: ANSI: %d args before, anon @ #%d, %dtime\n",
3377 ca->regs, *pretend_arg_size, second_time);
558d352a
KH
3378}
3379
52090e4d 3380/* Return true if ARG must be passed by invisible reference.
8cd5a4e0
RH
3381 For cris, we pass <= 8 bytes by value, others by reference. */
3382
3383static bool
52090e4d 3384cris_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
8cd5a4e0 3385{
0ffef200 3386 return (targetm.calls.must_pass_in_stack (arg)
52090e4d 3387 || CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8);
8cd5a4e0
RH
3388}
3389
cde0f3fd
PB
3390/* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments
3391 and *not* defining TARGET_PROMOTE_PROTOTYPES or PROMOTE_MODE gives the
3392 best code size and speed for gcc, ipps and products in gcc-2.7.2. */
3393
ef4bddc2 3394machine_mode
cde0f3fd 3395cris_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
ef4bddc2 3396 machine_mode mode,
cde0f3fd
PB
3397 int *punsignedp ATTRIBUTE_UNUSED,
3398 const_tree fntype ATTRIBUTE_UNUSED,
3399 int for_return)
3400{
3401 /* Defining PROMOTE_FUNCTION_RETURN in gcc-2.7.2 uncovered bug 981110 (even
4d696ad0
AS
3402 when modifying TARGET_FUNCTION_VALUE to return the promoted mode).
3403 Maybe pointless as of now, but let's keep the old behavior. */
666e3ceb 3404 if (for_return == 1)
cde0f3fd
PB
3405 return mode;
3406 return CRIS_PROMOTED_MODE (mode, *punsignedp, type);
3407}
3408
faee0106
HPN
3409/* Atomic types require alignment to be at least their "natural" size. */
3410
3411static unsigned int
ef4bddc2 3412cris_atomic_align_for_mode (machine_mode mode)
faee0106
HPN
3413{
3414 return GET_MODE_BITSIZE (mode);
3415}
3416
4d696ad0
AS
3417/* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the
3418 time being. */
3419
3420static rtx
3421cris_function_value(const_tree type,
3422 const_tree func ATTRIBUTE_UNUSED,
3423 bool outgoing ATTRIBUTE_UNUSED)
3424{
3425 return gen_rtx_REG (TYPE_MODE (type), CRIS_FIRST_ARG_REG);
3426}
3427
3428/* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the
3429 time being. */
3430
3431static rtx
ef4bddc2 3432cris_libcall_value (machine_mode mode,
4d696ad0
AS
3433 const_rtx fun ATTRIBUTE_UNUSED)
3434{
3435 return gen_rtx_REG (mode, CRIS_FIRST_ARG_REG);
3436}
3437
3438/* Let's assume all functions return in r[CRIS_FIRST_ARG_REG] for the
3439 time being. */
3440
2283c416 3441static bool
4d696ad0
AS
3442cris_function_value_regno_p (const unsigned int regno)
3443{
3444 return (regno == CRIS_FIRST_ARG_REG);
3445}
8cd5a4e0 3446
78a52f11 3447static int
a7c81bc1 3448cris_arg_partial_bytes (cumulative_args_t ca, const function_arg_info &arg)
78a52f11 3449{
d5cc9181 3450 if (get_cumulative_args (ca)->regs == CRIS_MAX_ARGS_IN_REGS - 1
0ffef200 3451 && !targetm.calls.must_pass_in_stack (arg)
a7c81bc1
RS
3452 && CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 4
3453 && CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) <= 8)
78a52f11
RH
3454 return UNITS_PER_WORD;
3455 else
3456 return 0;
3457}
3458
73f3f841 3459static rtx
6783fdb7
RS
3460cris_function_arg_1 (cumulative_args_t ca_v, const function_arg_info &arg,
3461 bool incoming)
73f3f841 3462{
d5cc9181
JR
3463 const CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
3464
6783fdb7
RS
3465 if ((!incoming || arg.named) && ca->regs < CRIS_MAX_ARGS_IN_REGS)
3466 return gen_rtx_REG (arg.mode, CRIS_FIRST_ARG_REG + ca->regs);
73f3f841
NF
3467 else
3468 return NULL_RTX;
3469}
3470
3471/* Worker function for TARGET_FUNCTION_ARG.
3472 The void_type_node is sent as a "closing" call. */
3473
3474static rtx
6783fdb7 3475cris_function_arg (cumulative_args_t ca, const function_arg_info &arg)
73f3f841 3476{
6783fdb7 3477 return cris_function_arg_1 (ca, arg, false);
73f3f841
NF
3478}
3479
3480/* Worker function for TARGET_FUNCTION_INCOMING_ARG.
3481
3482 The differences between this and the previous, is that this one checks
3483 that an argument is named, since incoming stdarg/varargs arguments are
3484 pushed onto the stack, and we don't have to check against the "closing"
6783fdb7 3485 function_arg_info::end_marker parameter. */
73f3f841
NF
3486
3487static rtx
6783fdb7 3488cris_function_incoming_arg (cumulative_args_t ca, const function_arg_info &arg)
73f3f841 3489{
6783fdb7 3490 return cris_function_arg_1 (ca, arg, true);
73f3f841
NF
3491}
3492
3493/* Worker function for TARGET_FUNCTION_ARG_ADVANCE. */
3494
3495static void
6930c98c
RS
3496cris_function_arg_advance (cumulative_args_t ca_v,
3497 const function_arg_info &arg)
73f3f841 3498{
d5cc9181
JR
3499 CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
3500
6930c98c 3501 ca->regs += (3 + CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type)) / 4;
73f3f841
NF
3502}
3503
7ca35180 3504/* Worker function for TARGET_MD_ASM_ADJUST. */
f60c7155 3505
7ca35180
RH
3506static rtx_insn *
3507cris_md_asm_adjust (vec<rtx> &outputs, vec<rtx> &inputs,
e52ef6e6
IL
3508 vec<machine_mode> & /*input_modes*/,
3509 vec<const char *> &constraints, vec<rtx> &clobbers,
8d76ff99 3510 HARD_REG_SET &clobbered_regs, location_t /*loc*/)
f60c7155 3511{
7ca35180
RH
3512 /* For the time being, all asms clobber condition codes.
3513 Revisit when there's a reasonable use for inputs/outputs
3514 that mention condition codes. */
3515 clobbers.safe_push (gen_rtx_REG (CCmode, CRIS_CC0_REGNUM));
3516 SET_HARD_REG_BIT (clobbered_regs, CRIS_CC0_REGNUM);
3517
3518 /* Determine if the source using MOF. If it is, automatically
3519 clobbering MOF would cause it to have impossible constraints. */
3520
3521 /* Look for a use of the MOF constraint letter: h. */
3522 for (unsigned i = 0, n = constraints.length(); i < n; ++i)
3523 if (strchr (constraints[i], 'h') != NULL)
3524 return NULL;
3525
3526 /* Look for an output or an input that touches MOF. */
3527 rtx mof_reg = gen_rtx_REG (SImode, CRIS_MOF_REGNUM);
3528 for (unsigned i = 0, n = outputs.length(); i < n; ++i)
3529 if (reg_overlap_mentioned_p (mof_reg, outputs[i]))
3530 return NULL;
3531 for (unsigned i = 0, n = inputs.length(); i < n; ++i)
3532 if (reg_overlap_mentioned_p (mof_reg, inputs[i]))
3533 return NULL;
3534
3535 /* No direct reference to MOF or its constraint.
3536 Clobber it for backward compatibility. */
3537 clobbers.safe_push (mof_reg);
3538 SET_HARD_REG_BIT (clobbered_regs, CRIS_MOF_REGNUM);
3539 return NULL;
f60c7155 3540}
78a52f11 3541
b52b1749
AS
3542/* Implement TARGET_FRAME_POINTER_REQUIRED.
3543
3544 Really only needed if the stack frame has variable length (alloca
3545 or variable sized local arguments (GNU C extension). See PR39499 and
3546 PR38609 for the reason this isn't just 0. */
3547
3548bool
3549cris_frame_pointer_required (void)
3550{
416ff32e 3551 return !crtl->sp_is_unchanging;
b52b1749
AS
3552}
3553
3e322b77
RH
3554/* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE.
3555
3556 This looks too complicated, and it is. I assigned r7 to be the
3557 static chain register, but it is call-saved, so we have to save it,
3558 and come back to restore it after the call, so we have to save srp...
3559 Anyway, trampolines are rare enough that we can cope with this
3560 somewhat lack of elegance.
3561 (Do not be tempted to "straighten up" whitespace in the asms; the
3562 assembler #NO_APP state mandates strict spacing). */
3563/* ??? See the i386 regparm=3 implementation that pushes the static
3564 chain value to the stack in the trampoline, and uses a call-saved
3565 register when called directly. */
3566
3567static void
3568cris_asm_trampoline_template (FILE *f)
3569{
d0780379
HPN
3570 fprintf (f, "\tmove.d $%s,[$pc+20]\n", reg_names[STATIC_CHAIN_REGNUM]);
3571 fprintf (f, "\tmove $srp,[$pc+22]\n");
3572 fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
3573 fprintf (f, "\tjsr 0\n");
3574 fprintf (f, "\tmove.d 0,$%s\n", reg_names[STATIC_CHAIN_REGNUM]);
3575 fprintf (f, "\tjump 0\n");
3e322b77
RH
3576}
3577
3578/* Implement TARGET_TRAMPOLINE_INIT. */
3579
3580static void
3581cris_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
3582{
3583 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3e322b77
RH
3584 rtx mem;
3585
3586 emit_block_move (m_tramp, assemble_trampoline_template (),
3587 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3588
d0780379
HPN
3589 mem = adjust_address (m_tramp, SImode, 10);
3590 emit_move_insn (mem, chain_value);
3591 mem = adjust_address (m_tramp, SImode, 16);
3592 emit_move_insn (mem, fnaddr);
3e322b77
RH
3593
3594 /* Note that there is no need to do anything with the cache for
3595 sake of a trampoline. */
3596}
3597
c43f4279
RS
3598/* Implement TARGET_HARD_REGNO_NREGS.
3599
3600 The VOIDmode test is so we can omit mode on anonymous insns. FIXME:
3601 Still needed in 2.9x, at least for Axis-20000319. */
3602
3603static unsigned int
3604cris_hard_regno_nregs (unsigned int, machine_mode mode)
3605{
3606 if (mode == VOIDmode)
3607 return 1;
3608 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
3609}
3610
f939c3e6
RS
3611/* Implement TARGET_HARD_REGNO_MODE_OK.
3612
3613 CRIS permits all registers to hold all modes. Well, except for the
3614 condition-code register. And we can't hold larger-than-register size
3615 modes in the last special register that can hold a full 32 bits. */
3616static bool
3617cris_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
3618{
3619 return ((mode == CCmode || regno != CRIS_CC0_REGNUM)
3620 && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
d0780379 3621 || regno != CRIS_MOF_REGNUM));
f939c3e6 3622}
3e322b77 3623
f073de07
RS
3624/* Return the preferred minimum alignment for a static object. */
3625
3626static HOST_WIDE_INT
bfb31c3d 3627cris_preferred_minimum_alignment (void)
f073de07
RS
3628{
3629 if (!TARGET_CONST_ALIGN)
3630 return 8;
3631 if (TARGET_ALIGN_BY_32)
3632 return 32;
3633 return 16;
3634}
3635
3636/* Implement TARGET_STATIC_RTX_ALIGNMENT. */
3637
3638static HOST_WIDE_INT
3639cris_static_rtx_alignment (machine_mode mode)
3640{
bfb31c3d 3641 return MAX (cris_preferred_minimum_alignment (), GET_MODE_ALIGNMENT (mode));
f073de07
RS
3642}
3643
58e17cf8
RS
3644/* Implement TARGET_CONSTANT_ALIGNMENT. Note that this hook has the
3645 effect of making gcc believe that ALL references to constant stuff
3646 (in code segment, like strings) have this alignment. That is a rather
3647 rushed assumption. Luckily we do not care about the "alignment"
3648 operand to builtin memcpy (only place where it counts), so it doesn't
3649 affect any bad spots. */
3650
3651static HOST_WIDE_INT
3652cris_constant_alignment (const_tree, HOST_WIDE_INT basic_align)
3653{
bfb31c3d 3654 return MAX (cris_preferred_minimum_alignment (), basic_align);
58e17cf8
RS
3655}
3656
0b85d816
HPN
3657#if 0
3658/* Various small functions to replace macros. Only called from a
3659 debugger. They might collide with gcc functions or system functions,
3660 so only emit them when '#if 1' above. */
3661
6640377c 3662enum rtx_code Get_code (rtx);
0b85d816
HPN
3663
3664enum rtx_code
6640377c 3665Get_code (rtx x)
0b85d816
HPN
3666{
3667 return GET_CODE (x);
3668}
3669
6640377c 3670const char *Get_mode (rtx);
0b85d816
HPN
3671
3672const char *
6640377c 3673Get_mode (rtx x)
0b85d816
HPN
3674{
3675 return GET_MODE_NAME (GET_MODE (x));
3676}
3677
6640377c 3678rtx Xexp (rtx, int);
0b85d816
HPN
3679
3680rtx
6640377c 3681Xexp (rtx x, int n)
0b85d816
HPN
3682{
3683 return XEXP (x, n);
3684}
3685
6640377c 3686rtx Xvecexp (rtx, int, int);
0b85d816
HPN
3687
3688rtx
6640377c 3689Xvecexp (rtx x, int n, int m)
117b0c0a 3690{
0b85d816
HPN
3691 return XVECEXP (x, n, m);
3692}
3693
6640377c 3694int Get_rtx_len (rtx);
0b85d816
HPN
3695
3696int
6640377c 3697Get_rtx_len (rtx x)
0b85d816
HPN
3698{
3699 return GET_RTX_LENGTH (GET_CODE (x));
3700}
3701
3702/* Use upper-case to distinguish from local variables that are sometimes
3703 called next_insn and prev_insn. */
3704
6640377c 3705rtx Next_insn (rtx);
0b85d816
HPN
3706
3707rtx
6640377c 3708Next_insn (rtx insn)
0b85d816
HPN
3709{
3710 return NEXT_INSN (insn);
3711}
3712
6640377c 3713rtx Prev_insn (rtx);
0b85d816
HPN
3714
3715rtx
6640377c 3716Prev_insn (rtx insn)
0b85d816
HPN
3717{
3718 return PREV_INSN (insn);
3719}
3720#endif
3721
e2500fed
GK
3722#include "gt-cris.h"
3723
0b85d816
HPN
3724/*
3725 * Local variables:
3726 * eval: (c-set-style "gnu")
3727 * indent-tabs-mode: t
3728 * End:
3729 */