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