/* Definitions for GCC. Part of the machine description for CRIS.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Contributed by Axis Communications. Written by Hans-Peter Nilsson.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
static bool cris_rtx_costs (rtx, int, int, int *);
static int cris_address_cost (rtx);
static bool cris_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
- tree, bool);
+ const_tree, bool);
static int cris_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
static tree cris_md_asm_clobbers (tree, tree, tree);
#define TARGET_ADDRESS_COST cris_address_cost
#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX cris_struct_value_rtx
#undef TARGET_SETUP_INCOMING_VARARGS
other than (MEM reg). */
if (reg_count <= 1
|| GET_CODE (XVECEXP (op, 0, offs)) != SET
- || GET_CODE (SET_DEST (XVECEXP (op, 0, offs))) != REG
- || GET_CODE (SET_SRC (XVECEXP (op, 0, offs))) != MEM)
+ || !REG_P (SET_DEST (XVECEXP (op, 0, offs)))
+ || !MEM_P (SET_SRC (XVECEXP (op, 0, offs))))
return false;
/* Check a possible post-inc indicator. */
|| !REG_P (reg)
|| !REG_P (SET_DEST (XVECEXP (op, 0, offs + 1)))
|| REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, offs + 1)))
- || GET_CODE (inc) != CONST_INT
+ || !CONST_INT_P (inc)
|| INTVAL (inc) != (HOST_WIDE_INT) reg_count * 4)
return false;
i = offs + 2;
src_addr = XEXP (SET_SRC (elt), 0);
if (GET_CODE (elt) != SET
- || GET_CODE (SET_DEST (elt)) != REG
+ || !REG_P (SET_DEST (elt))
|| GET_MODE (SET_DEST (elt)) != SImode
|| REGNO (SET_DEST (elt)) != regno
- || GET_CODE (SET_SRC (elt)) != MEM
+ || !MEM_P (SET_SRC (elt))
|| GET_MODE (SET_SRC (elt)) != SImode
|| !memory_address_p (SImode, src_addr))
return false;
regno += regno_dir;
if (GET_CODE (elt) != SET
- || GET_CODE (SET_DEST (elt)) != REG
+ || !REG_P (SET_DEST (elt))
|| GET_MODE (SET_DEST (elt)) != SImode
|| REGNO (SET_DEST (elt)) != regno
- || GET_CODE (SET_SRC (elt)) != MEM
+ || !MEM_P (SET_SRC (elt))
|| GET_MODE (SET_SRC (elt)) != SImode
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
|| ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
- || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
+ || !CONST_INT_P (XEXP (XEXP (SET_SRC (elt), 0), 1))
|| INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != setno * 4)
return false;
}
dest = SET_DEST (elt);
- if (GET_CODE (SET_SRC (elt)) != REG
- || GET_CODE (dest) != MEM)
+ if (!REG_P (SET_SRC (elt)) || !MEM_P (dest))
return false;
dest_addr = XEXP (dest, 0);
|| !REG_P (reg)
|| !REG_P (SET_DEST (XVECEXP (op, 0, 1)))
|| REGNO (reg) != REGNO (SET_DEST (XVECEXP (op, 0, 1)))
- || GET_CODE (inc) != CONST_INT
+ || !CONST_INT_P (inc)
/* Support increment by number of registers, and by the offset
of the destination, if it has the form (MEM (PLUS reg
offset)). */
|| (GET_CODE (dest_addr) == PLUS
&& REG_P (XEXP (dest_addr, 0))
&& REGNO (XEXP (dest_addr, 0)) == REGNO (reg)
- && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT
+ && CONST_INT_P (XEXP (dest_addr, 1))
&& INTVAL (XEXP (dest_addr, 1)) == INTVAL (inc))))
return false;
regno = reg_count - 1;
if (GET_CODE (elt) != SET
- || GET_CODE (SET_SRC (elt)) != REG
+ || !REG_P (SET_SRC (elt))
|| GET_MODE (SET_SRC (elt)) != SImode
|| REGNO (SET_SRC (elt)) != (unsigned int) regno
- || GET_CODE (SET_DEST (elt)) != MEM
+ || !MEM_P (SET_DEST (elt))
|| GET_MODE (SET_DEST (elt)) != SImode)
return false;
}
else if (GET_CODE (dest_addr) == PLUS
&& REG_P (XEXP (dest_addr, 0))
- && GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (dest_addr, 1)))
{
dest_base = XEXP (dest_addr, 0);
offset = INTVAL (XEXP (dest_addr, 1));
regno += regno_dir;
if (GET_CODE (elt) != SET
- || GET_CODE (SET_SRC (elt)) != REG
+ || !REG_P (SET_SRC (elt))
|| GET_MODE (SET_SRC (elt)) != SImode
|| REGNO (SET_SRC (elt)) != (unsigned int) regno
- || GET_CODE (SET_DEST (elt)) != MEM
+ || !MEM_P (SET_DEST (elt))
|| GET_MODE (SET_DEST (elt)) != SImode
|| GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
|| ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_base)
- || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
+ || !CONST_INT_P (XEXP (XEXP (SET_DEST (elt), 0), 1))
|| INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != setno * 4 + offset)
return false;
}
static void
cris_print_index (rtx index, FILE *file)
{
- rtx inner = XEXP (index, 0);
-
/* Make the index "additive" unless we'll output a negative number, in
which case the sign character is free (as in free beer). */
- if (GET_CODE (index) != CONST_INT || INTVAL (index) >= 0)
+ if (!CONST_INT_P (index) || INTVAL (index) >= 0)
putc ('+', file);
if (REG_P (index))
putc (INTVAL (XEXP (index, 1)) == 2 ? 'w' : 'd', file);
}
- else if (GET_CODE (index) == SIGN_EXTEND &&
- GET_CODE (inner) == MEM)
+ else if (GET_CODE (index) == SIGN_EXTEND && MEM_P (XEXP (index, 0)))
{
+ rtx inner = XEXP (index, 0);
rtx inner_inner = XEXP (inner, 0);
if (GET_CODE (inner_inner) == POST_INC)
putc (GET_MODE (inner) == HImode ? 'w' : 'b', file);
}
}
- else if (GET_CODE (index) == MEM)
+ else if (MEM_P (index))
{
+ rtx inner = XEXP (index, 0);
if (GET_CODE (inner) == POST_INC)
fprintf (file, "[$%s+].d", reg_names[REGNO (XEXP (inner, 0))]);
else
cris_reg_saved_in_regsave_area (unsigned int regno, bool got_really_used)
{
return
- (((regs_ever_live[regno]
+ (((df_regs_ever_live_p (regno)
&& !call_used_regs[regno])
|| (regno == PIC_OFFSET_TABLE_REGNUM
&& (got_really_used
/* It is saved anyway, if there would be a gap. */
|| (flag_pic
- && regs_ever_live[regno + 1]
+ && df_regs_ever_live_p (regno + 1)
&& !call_used_regs[regno + 1]))))
&& (regno != FRAME_POINTER_REGNUM || !frame_pointer_needed)
&& regno != CRIS_SRP_REGNUM)
case 'b':
/* Print the unsigned supplied integer as if it were signed
and < 0, i.e print 255 or 65535 as -1, 254, 65534 as -2, etc. */
- if (GET_CODE (x) != CONST_INT
+ if (!CONST_INT_P (x)
|| ! CONST_OK_FOR_LETTER_P (INTVAL (x), 'O'))
LOSE_AND_RETURN ("invalid operand for 'b' modifier", x);
fprintf (file, HOST_WIDE_INT_PRINT_DEC,
/* The lowest mem operand is in the first item, but perhaps it
needs to be output as postincremented. */
- addr = GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == MEM
+ addr = MEM_P (SET_SRC (XVECEXP (x, 0, 0)))
? XEXP (SET_SRC (XVECEXP (x, 0, 0)), 0)
: XEXP (SET_DEST (XVECEXP (x, 0, 0)), 0);
case 'p':
/* Adjust a power of two to its log2. */
- if (GET_CODE (x) != CONST_INT || exact_log2 (INTVAL (x)) < 0 )
+ if (!CONST_INT_P (x) || exact_log2 (INTVAL (x)) < 0 )
LOSE_AND_RETURN ("invalid operand for 'p' modifier", x);
fprintf (file, "%d", exact_log2 (INTVAL (x)));
return;
respectively. This modifier also terminates the inhibiting
effects of the 'x' modifier. */
cris_output_insn_is_bound = 0;
- if (GET_MODE (x) == VOIDmode && GET_CODE (x) == CONST_INT)
+ if (GET_MODE (x) == VOIDmode && CONST_INT_P (x))
{
if (INTVAL (x) >= 0)
{
case 'z':
/* Const_int: print b for -127 <= x <= 255,
w for -32768 <= x <= 65535, else die. */
- if (GET_CODE (x) != CONST_INT
+ if (!CONST_INT_P (x)
|| INTVAL (x) < -32768 || INTVAL (x) > 65535)
LOSE_AND_RETURN ("invalid operand for 'z' modifier", x);
putc (INTVAL (x) >= -128 && INTVAL (x) <= 255 ? 'b' : 'w', file);
case 'e':
/* Like 'E', but ignore state set by 'x'. FIXME: Use code
- iterators ("code macros") and attributes in cris.md to avoid
- the need for %x and %E (and %e) and state passed between
- those modifiers. */
+ iterators and attributes in cris.md to avoid the need for %x
+ and %E (and %e) and state passed between those modifiers. */
cris_output_insn_is_bound = 0;
/* FALL THROUGH. */
case 'E':
cris_output_insn_is_bound is nonzero. */
if (GET_CODE (operand) != SIGN_EXTEND
&& GET_CODE (operand) != ZERO_EXTEND
- && GET_CODE (operand) != CONST_INT)
+ && !CONST_INT_P (operand))
LOSE_AND_RETURN ("invalid operand for 'e' modifier", x);
if (cris_output_insn_is_bound)
}
putc (GET_CODE (operand) == SIGN_EXTEND
- || (GET_CODE (operand) == CONST_INT && INTVAL (operand) < 0)
+ || (CONST_INT_P (operand) && INTVAL (operand) < 0)
? 's' : 'u', file);
return;
fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
return;
}
- else if (HOST_BITS_PER_WIDE_INT > 32 && GET_CODE (operand) == CONST_INT)
+ else if (HOST_BITS_PER_WIDE_INT > 32 && CONST_INT_P (operand))
{
fprintf (file, HOST_WIDE_INT_PRINT_HEX,
INTVAL (x) & ((unsigned int) 0x7fffffff * 2 + 1));
case 'A':
/* When emitting an add for the high part of a DImode constant, we
want to use addq for 0 and adds.w for -1. */
- if (GET_CODE (operand) != CONST_INT)
+ if (!CONST_INT_P (operand))
LOSE_AND_RETURN ("invalid operand for 'A' modifier", x);
fprintf (file, INTVAL (operand) < 0 ? "adds.w" : "addq");
return;
case 'D':
/* When emitting an sub for the high part of a DImode constant, we
want to use subq for 0 and subs.w for -1. */
- if (GET_CODE (operand) != CONST_INT)
+ if (!CONST_INT_P (operand))
LOSE_AND_RETURN ("invalid operand for 'D' modifier", x);
fprintf (file, INTVAL (operand) < 0 ? "subs.w" : "subq");
return;
case 'T':
/* Print the size letter for an operand to a MULT, which must be a
const_int with a suitable value. */
- if (GET_CODE (operand) != CONST_INT || INTVAL (operand) > 4)
+ if (!CONST_INT_P (operand) || INTVAL (operand) > 4)
LOSE_AND_RETURN ("invalid operand for 'T' modifier", x);
fprintf (file, "%s", mults[INTVAL (operand)]);
return;
case ASHIFT:
{
/* For a (MULT (reg X) const_int) we output "rX.S". */
- int i = GET_CODE (XEXP (operand, 1)) == CONST_INT
+ int i = CONST_INT_P (XEXP (operand, 1))
? INTVAL (XEXP (operand, 1)) : INTVAL (XEXP (operand, 0));
- rtx reg = GET_CODE (XEXP (operand, 1)) == CONST_INT
+ rtx reg = CONST_INT_P (XEXP (operand, 1))
? XEXP (operand, 0) : XEXP (operand, 1);
- if (GET_CODE (reg) != REG
- || (GET_CODE (XEXP (operand, 0)) != CONST_INT
- && GET_CODE (XEXP (operand, 1)) != CONST_INT))
+ if (!REG_P (reg)
+ || (!CONST_INT_P (XEXP (operand, 0))
+ && !CONST_INT_P (XEXP (operand, 1))))
LOSE_AND_RETURN ("unexpected multiplicative operand", x);
cris_print_base (reg, file);
else
LOSE_AND_RETURN ("unrecognized address", x);
}
- else if (GET_CODE (x) == MEM)
+ else if (MEM_P (x))
{
/* A DIP. Output more indirection characters. */
putc ('[', file);
bool
cris_return_address_on_stack (void)
{
- return regs_ever_live[CRIS_SRP_REGNUM]
+ return df_regs_ever_live_p (CRIS_SRP_REGNUM)
|| cfun->machine->needs_return_address_on_stack;
}
if (!REG_P (op1))
return false;
- if (GET_CODE (op0) == SIGN_EXTEND
- && GET_CODE (XEXP (op0, 0)) == MEM)
+ if (GET_CODE (op0) == SIGN_EXTEND && MEM_P (XEXP (op0, 0)))
{
rtx op00 = XEXP (op0, 0);
rtx op000 = XEXP (op00, 0);
if (GET_CODE (SET_SRC (exp)) == ZERO_EXTRACT
&& XEXP (SET_SRC (exp), 1) == const1_rtx)
{
- if (GET_CODE (XEXP (SET_SRC (exp), 0)) == CONST_INT)
+ if (CONST_INT_P (XEXP (SET_SRC (exp), 0)))
/* Using cmpq. */
cc_status.flags = CC_INVERTED;
else
return;
}
}
- else if (GET_CODE (SET_DEST (exp)) == MEM
+ else if (MEM_P (SET_DEST (exp))
|| (GET_CODE (SET_DEST (exp)) == STRICT_LOW_PART
- && GET_CODE (XEXP (SET_DEST (exp), 0)) == MEM))
+ && MEM_P (XEXP (SET_DEST (exp), 0))))
{
/* When SET to MEM, then CC is not changed (except for
overlap). */
&& REG_P (XEXP (XVECEXP (exp, 0, 1), 0)))
{
if (REG_P (XEXP (XVECEXP (exp, 0, 0), 0))
- && GET_CODE (XEXP (XVECEXP (exp, 0, 0), 1)) == MEM)
+ && MEM_P (XEXP (XVECEXP (exp, 0, 0), 1)))
{
/* For "move.S [rx=ry+o],rz", say CC reflects
value1=rz and value2=[rx] */
}
else if ((REG_P (XEXP (XVECEXP (exp, 0, 0), 1))
|| XEXP (XVECEXP (exp, 0, 0), 1) == const0_rtx)
- && GET_CODE (XEXP (XVECEXP (exp, 0, 0), 0)) == MEM)
+ && MEM_P (XEXP (XVECEXP (exp, 0, 0), 0)))
{
/* For "move.S rz,[rx=ry+o]" and "clear.S [rx=ry+o]",
say flags are not changed, except for overlap. */
/* Eight or 16 bits are a word and cycle more expensive. */
else if (val <= 32767 && val >= -32768)
*total = 2;
- /* A 32 bit constant (or very seldom, unsigned 16 bits) costs
+ /* A 32-bit constant (or very seldom, unsigned 16 bits) costs
another word. FIXME: This isn't linear to 16 bits. */
else
*total = 4;
case MULT:
/* Identify values that are no powers of two. Powers of 2 are
taken care of already and those values should not be changed. */
- if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ if (!CONST_INT_P (XEXP (x, 1))
|| exact_log2 (INTVAL (XEXP (x, 1)) < 0))
{
/* If we have a multiply insn, then the cost is between
case MOD:
case UMOD:
case DIV:
- if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ if (!CONST_INT_P (XEXP (x, 1))
|| exact_log2 (INTVAL (XEXP (x, 1)) < 0))
{
/* Estimate this as 4 + 8 * #of bits. */
return false;
case AND:
- if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ if (CONST_INT_P (XEXP (x, 1))
/* Two constants may actually happen before optimization. */
- && GET_CODE (XEXP (x, 0)) != CONST_INT
+ && !CONST_INT_P (XEXP (x, 0))
&& !CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
{
*total = (rtx_cost (XEXP (x, 0), outer_code) + 2
/* An indirect mem must be a DIP. This means two bytes extra for code,
and 4 bytes extra for memory read, i.e. (2 + 4) / 2. */
- if (GET_CODE (x) == MEM)
+ if (MEM_P (x))
return (2 + 4) / 2;
/* Assume (2 + 4) / 2 for a single constant; a dword, since it needs
/* A BDAP (quick) is 2 extra bytes. Any constant operand to the
PLUS is always found in tem2. */
- if (GET_CODE (tem2) == CONST_INT
- && INTVAL (tem2) < 128 && INTVAL (tem2) >= -128)
+ if (CONST_INT_P (tem2) && INTVAL (tem2) < 128 && INTVAL (tem2) >= -128)
return 2 / 2;
/* A BDAP -32768 .. 32767 is like BDAP quick, but with 2 extra
bytes. */
- if (GET_CODE (tem2) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (tem2), 'L'))
+ if (CONST_INT_P (tem2) && CONST_OK_FOR_LETTER_P (INTVAL (tem2), 'L'))
return (2 + 2) / 2;
/* A BDAP with some other constant is 2 bytes extra. */
/* Do not allow rx = rx + n if a normal add or sub with same size
would do. */
if (rtx_equal_p (ops[lreg], reg_rtx)
- && GET_CODE (val_rtx) == CONST_INT
+ && CONST_INT_P (val_rtx)
&& (INTVAL (val_rtx) <= 63 && INTVAL (val_rtx) >= -63))
return 0;
if (CONSTANT_P (val_rtx))
return 1;
- if (GET_CODE (val_rtx) == MEM
- && BASE_OR_AUTOINCR_P (XEXP (val_rtx, 0)))
+ if (MEM_P (val_rtx) && BASE_OR_AUTOINCR_P (XEXP (val_rtx, 0)))
return 1;
if (GET_CODE (val_rtx) == SIGN_EXTEND
- && GET_CODE (XEXP (val_rtx, 0)) == MEM
+ && MEM_P (XEXP (val_rtx, 0))
&& BASE_OR_AUTOINCR_P (XEXP (XEXP (val_rtx, 0), 0)))
return 1;
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == UNSPEC
&& XINT (XEXP (x, 0), 1) == CRIS_UNSPEC_GOTREL
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ && CONST_INT_P (XEXP (x, 1)))
x = XEXP (x, 0);
if (GET_CODE (x) == UNSPEC)
CRIS_ASSERT (GET_CODE (dest) != SUBREG && GET_CODE (src) != SUBREG);
start_sequence ();
- if (GET_CODE (dest) == REG)
+ if (REG_P (dest))
{
int dregno = REGNO (dest);
/* Reg-to-reg copy. */
- if (GET_CODE (src) == REG)
+ if (REG_P (src))
{
int sregno = REGNO (src);
operand_subword (src, !reverse, TRUE, mode)));
}
/* Constant-to-reg copy. */
- else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
+ else if (CONST_INT_P (src) || GET_CODE (src) == CONST_DOUBLE)
{
rtx words[2];
split_double (src, &words[0], &words[1]);
words[1]));
}
/* Mem-to-reg copy. */
- else if (GET_CODE (src) == MEM)
+ else if (MEM_P (src))
{
/* If the high-address word is used in the address, we must load it
last. Otherwise, load it first. */
internal_error ("Unknown src");
}
/* Reg-to-mem copy or clear mem. */
- else if (GET_CODE (dest) == MEM
- && (GET_CODE (src) == REG
+ else if (MEM_P (dest)
+ && (REG_P (src)
|| src == const0_rtx
|| src == CONST0_RTX (DFmode)))
{
{
rtx mem;
rtx insn;
-
+
/* Whenever we emit insns with post-incremented addresses
ourselves, we must add a post-inc note manually. */
mem = change_address (dest, SImode, addr);
if (increment != 0)
{
rtx seq = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nregs + 1));
- XVECEXP (seq, 0, 0) = XVECEXP (PATTERN (insn), 0, 0);
+ XVECEXP (seq, 0, 0) = copy_rtx (XVECEXP (PATTERN (insn), 0, 0));
for (i = 1; i < nregs; i++)
- XVECEXP (seq, 0, i) = XVECEXP (PATTERN (insn), 0, i + 1);
- XVECEXP (seq, 0, nregs) = XVECEXP (PATTERN (insn), 0, 1);
+ XVECEXP (seq, 0, i)
+ = copy_rtx (XVECEXP (PATTERN (insn), 0, i + 1));
+ XVECEXP (seq, 0, nregs) = copy_rtx (XVECEXP (PATTERN (insn), 0, 1));
REG_NOTES (insn)
= gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, seq,
REG_NOTES (insn));
/* It might be that code can be generated that jumps to 0 (or to a
specific address). Don't die on that. (There is a
testcase.) */
- if (CONSTANT_ADDRESS_P (op) && GET_CODE (op) != CONST_INT)
+ if (CONSTANT_ADDRESS_P (op) && !CONST_INT_P (op))
{
enum cris_pic_symbol_type t = cris_pic_symbol_type_of (op);
- CRIS_ASSERT (!no_new_pseudos);
+ CRIS_ASSERT (can_create_pseudo_p ());
/* For local symbols (non-PLT), just get the plain symbol
reference into a register. For symbols that can be PLT, make
"move.d (const (unspec [sym] CRIS_UNSPEC_PLT)),rM"
"add.d rPIC,rM,rO", "jsr rO". */
rtx tem, rm, ro;
- gcc_assert (! no_new_pseudos);
+ gcc_assert (can_create_pseudo_p ());
current_function_uses_pic_offset_table = 1;
tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op), CRIS_UNSPEC_PLT);
rm = gen_reg_rtx (Pmode);
access of the PLTGOT isn't constant). */
rtx tem, mem, rm, ro;
- gcc_assert (! no_new_pseudos);
+ gcc_assert (can_create_pseudo_p ());
current_function_uses_pic_offset_table = 1;
tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op),
CRIS_UNSPEC_PLTGOTREAD);
}
}
+/* Make sure operands are in the right order for an addsi3 insn as
+ generated by a define_split. A MEM as the first operand isn't
+ recognized by addsi3 after reload. OPERANDS contains the operands,
+ with the first at OPERANDS[N] and the second at OPERANDS[N+1]. */
+
+void
+cris_order_for_addsi3 (rtx *operands, int n)
+{
+ if (MEM_P (operands[n]))
+ {
+ rtx tem = operands[n];
+ operands[n] = operands[n + 1];
+ operands[n + 1] = tem;
+ }
+}
+
/* Use from within code, from e.g. PRINT_OPERAND and
PRINT_OPERAND_ADDRESS. Macros used in output_addr_const need to emit
different things depending on whether code operand or constant is
static bool
cris_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
- enum machine_mode mode, tree type,
+ enum machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{
return (targetm.calls.must_pass_in_stack (mode, type)
impossible constraints. */
if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))),
'h') != NULL
- || decl_overlaps_hard_reg_set_p (val, mof_set))
+ || tree_overlaps_hard_reg_set (val, &mof_set) != NULL_TREE)
return clobbers;
}
if (strchr (TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))),
'h') != NULL
- || decl_overlaps_hard_reg_set_p (val, mof_set))
+ || tree_overlaps_hard_reg_set (val, &mof_set) != NULL_TREE)
return clobbers;
}