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