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