/* Output routines for Motorola MCore processor
- Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright (C) 1993, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of GCC.
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, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "config.h"
#include "system.h"
/* Maximum size we are allowed to grow the stack in a single operation.
If we want more, we must do it in increments of at most this size.
If this value is 0, we don't check at all. */
-const char * mcore_stack_increment_string = 0;
-int mcore_stack_increment = STACK_UNITS_MAXSTEP;
+int mcore_stack_increment = STACK_UNITS_MAXSTEP;
/* For dumping information about frame sizes. */
char * mcore_current_function_name = 0;
static void output_stack_adjust (int, int);
static int calc_live_regs (int *);
-static int const_ok_for_mcore (int);
static int try_constant_tricks (long, int *, int *);
static const char * output_inline_const (enum machine_mode, rtx *);
-static void block_move_sequence (rtx, rtx, rtx, rtx, int, int, int);
static void layout_mcore_frame (struct mcore_frame *);
static void mcore_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
static cond_type is_cond_candidate (rtx);
static tree mcore_handle_naked_attribute (tree *, tree, tree, int, bool *);
#ifdef OBJECT_FORMAT_ELF
static void mcore_asm_named_section (const char *,
- unsigned int);
+ unsigned int, tree);
#endif
static void mcore_unique_section (tree, int);
static void mcore_encode_section_info (tree, rtx, int);
static bool mcore_rtx_costs (rtx, int, int, int *);
static void mcore_external_libcall (rtx);
static bool mcore_return_in_memory (tree, tree);
+static int mcore_arg_partial_bytes (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, bool);
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_EXTERNAL_LIBCALL
#define TARGET_ASM_EXTERNAL_LIBCALL mcore_external_libcall
-#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
#undef TARGET_MERGE_DECL_ATTRIBUTES
#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
#endif
#define TARGET_ATTRIBUTE_TABLE mcore_attribute_table
#undef TARGET_ASM_UNIQUE_SECTION
#define TARGET_ASM_UNIQUE_SECTION mcore_unique_section
+#undef TARGET_ASM_FUNCTION_RODATA_SECTION
+#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
+#undef TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO mcore_encode_section_info
#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
+#undef TARGET_ARG_PARTIAL_BYTES
+#define TARGET_ARG_PARTIAL_BYTES mcore_arg_partial_bytes
#undef TARGET_SETUP_INCOMING_VARARGS
#define TARGET_SETUP_INCOMING_VARARGS mcore_setup_incoming_varargs
break;
default:
- debug_rtx (x);
-
- abort ();
+ gcc_unreachable ();
}
}
/* Print operand x (an rtx) in assembler syntax to file stream
according to modifier code.
- 'R' print the next register or memory location along, ie the lsw in
+ 'R' print the next register or memory location along, i.e. the lsw in
a double word value
'O' print a constant without the #
'M' print a constant as its negative
(stream, XEXP (adjust_address (x, SImode, 4), 0));
break;
default:
- abort ();
+ gcc_unreachable ();
}
break;
case 'U':
break;
case GTU: /* Use inverted condition, cmple. */
- if (GET_CODE (op1) == CONST_INT && INTVAL (op1) == 0)
- {
- /* Unsigned > 0 is the same as != 0, but we need
- to invert the condition, so we want to set
- code = EQ. This cannot be done however, as the
- mcore does not support such a test. Instead we
- cope with this case in the "bgtu" pattern itself
- so we should never reach this point. */
- /* code = EQ; */
- abort ();
- break;
- }
+ /* Unsigned > 0 is the same as != 0, but we need to invert the
+ condition, so we want to set code = EQ. This cannot be done
+ however, as the mcore does not support such a test. Instead
+ we cope with this case in the "bgtu" pattern itself so we
+ should never reach this point. */
+ gcc_assert (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0);
code = LEU;
/* Drop through. */
}
}
-int
-mcore_call_address_operand (rtx x, enum machine_mode mode)
-{
- return register_operand (x, mode) || CONSTANT_P (x);
-}
-
/* Functions to output assembly code for a function call. */
char *
{
if (TARGET_CG_DATA)
{
- if (mcore_current_function_name == 0)
- abort ();
+ gcc_assert (mcore_current_function_name);
ASM_OUTPUT_CG_EDGE (asm_out_file, mcore_current_function_name,
"unknown", 1);
{
if (TARGET_CG_DATA)
{
- if (mcore_current_function_name == 0)
- abort ();
+ gcc_assert (mcore_current_function_name);
+ gcc_assert (GET_CODE (addr) == SYMBOL_REF);
- if (GET_CODE (addr) != SYMBOL_REF)
- abort ();
-
- ASM_OUTPUT_CG_EDGE (asm_out_file, mcore_current_function_name, XSTR (addr, 0), 0);
+ ASM_OUTPUT_CG_EDGE (asm_out_file, mcore_current_function_name,
+ XSTR (addr, 0), 0);
}
sprintf (buffer, "jbsr\t%%%d", index);
/* Can we load a constant with a single instruction ? */
-static int
+int
const_ok_for_mcore (int value)
{
if (value >= 0 && value <= 127)
}
}
- /* No conclusive evidence either way, we can not take the chance
+ /* No conclusive evidence either way, we cannot take the chance
that control flow hid the use from us -- "I'm not dead yet". */
return 0;
}
rtx out_operands[3];
const char * load_op;
char buf[256];
+ int trick_no;
- if (try_constant_tricks (INTVAL (operands[1]), &x, &y) != 2)
- abort ();
+ trick_no = try_constant_tricks (INTVAL (operands[1]), &x, &y);
+ gcc_assert (trick_no == 2);
out_operands[0] = operands[0];
out_operands[1] = GEN_INT(x);
int value;
value = INTVAL (operands[1]);
-
- if ((trick_no = try_constant_tricks (value, &x, &y)) == 0)
- {
- /* lrw's are handled separately: Large inlinable constants
- never get turned into lrw's. Our caller uses try_constant_tricks
- to back off to an lrw rather than calling this routine. */
- abort ();
- }
+ trick_no = try_constant_tricks (value, &x, &y);
+ /* lrw's are handled separately: Large inlinable constants never get
+ turned into lrw's. Our caller uses try_constant_tricks to back
+ off to an lrw rather than calling this routine. */
+ gcc_assert (trick_no != 0);
+
if (trick_no == 1)
x = value;
case QImode:
return "ld.b\t%0,%1";
default:
- abort ();
+ gcc_unreachable ();
}
}
else if (GET_CODE (src) == CONST_INT)
case QImode:
return "st.b\t%1,%0";
default:
- abort ();
+ gcc_unreachable ();
}
- abort ();
+ gcc_unreachable ();
}
/* Return a sequence of instructions to perform DI or DF move.
else if (GET_CODE (XEXP (memexp, 1)) == REG)
basereg = REGNO (XEXP (memexp, 1));
else
- abort ();
+ gcc_unreachable ();
}
else
- abort ();
+ gcc_unreachable ();
/* ??? length attribute is wrong here. */
if (dstreg == basereg)
else if (CONST_OK_FOR_N (INTVAL (src)))
output_asm_insn ("bmaski %0,%N1", operands);
else
- abort ();
+ gcc_unreachable ();
if (INTVAL (src) < 0)
return "bmaski %R0,32";
else if (CONST_OK_FOR_N (INTVAL (src)))
output_asm_insn ("bmaski %R0,%N1", operands);
else
- abort ();
+ gcc_unreachable ();
if (INTVAL (src) < 0)
return "bmaski %0,32";
}
}
else
- abort ();
+ gcc_unreachable ();
}
else if (GET_CODE (dst) == MEM && GET_CODE (src) == REG)
return "stw\t%1,%0\n\tstw\t%R1,%R0";
else
- abort ();
+ gcc_unreachable ();
}
/* Predicates used by the templates. */
-/* Nonzero if OP can be source of a simple move operation. */
-
-int
-mcore_general_movsrc_operand (rtx op, enum machine_mode mode)
-{
- /* Any (MEM LABEL_REF) is OK. That is a pc-relative load. */
- if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == LABEL_REF)
- return 1;
-
- return general_operand (op, mode);
-}
-
-/* Nonzero if OP can be destination of a simple move operation. */
-
-int
-mcore_general_movdst_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == REG && REGNO (op) == CC_REG)
- return 0;
-
- return general_operand (op, mode);
-}
-
-/* Nonzero if OP is a normal arithmetic register. */
-
-int
-mcore_arith_reg_operand (rtx op, enum machine_mode mode)
-{
- if (! register_operand (op, mode))
- return 0;
-
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
-
- if (GET_CODE (op) == REG)
- return REGNO (op) != CC_REG;
-
- return 1;
-}
-
-/* Nonzero if OP should be recognized during reload for an ixh/ixw
- operand. See the ixh/ixw patterns. */
-
-int
-mcore_reload_operand (rtx op, enum machine_mode mode)
-{
- if (mcore_arith_reg_operand (op, mode))
- return 1;
-
- if (! reload_in_progress)
- return 0;
-
- return GET_CODE (op) == MEM;
-}
-
-/* Nonzero if OP is a valid source operand for an arithmetic insn. */
-
-int
-mcore_arith_J_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for an arithmetic insn. */
-
-int
-mcore_arith_K_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for a shift or rotate insn. */
-
-int
-mcore_arith_K_operand_not_0 (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if ( GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_K (INTVAL (op))
- && INTVAL (op) != 0)
- return 1;
-
- return 0;
-}
-
-int
-mcore_arith_K_S_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT)
- {
- if (CONST_OK_FOR_K (INTVAL (op)) || CONST_OK_FOR_M (~INTVAL (op)))
- return 1;
- }
-
- return 0;
-}
-
int
mcore_arith_S_operand (rtx op)
{
return 0;
}
-int
-mcore_arith_M_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for loading. */
-
-int
-mcore_arith_imm_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT && const_ok_for_mcore (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-int
-mcore_arith_any_imm_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT)
- return 1;
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for a cmov with two consts +/- 1. */
-
-int
-mcore_arith_O_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_O (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for a btsti. */
-
-int
-mcore_literal_K_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for an add/sub insn. */
-
-int
-mcore_addsub_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT)
- {
- return 1;
-
- /* The following is removed because it precludes large constants from being
- returned as valid source operands for and add/sub insn. While large
- constants may not directly be used in an add/sub, they may if first loaded
- into a register. Thus, this predicate should indicate that they are valid,
- and the constraint in mcore.md should control whether an additional load to
- register is needed. (see mcore.md, addsi). -- DAC 4/2/1998 */
- /*
- if (CONST_OK_FOR_J(INTVAL(op)) || CONST_OK_FOR_L(INTVAL(op)))
- return 1;
- */
- }
-
- return 0;
-}
-
-/* Nonzero if OP is a valid source operand for a compare operation. */
-
-int
-mcore_compare_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
- return 1;
-
- return 0;
-}
-
/* Expand insert bit field. BRC */
int
return 1;
}
-
-/* Return 1 if OP is a load multiple operation. It is known to be a
- PARALLEL and the first section will be tested. */
-
-int
-mcore_load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- int count = XVECLEN (op, 0);
- int dest_regno;
- rtx src_addr;
- int i;
-
- /* Perform a quick check so we don't blow up below. */
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, 0)) != SET
- || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
- || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
- return 0;
-
- dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
- src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
-
- for (i = 1; i < count; i++)
- {
- rtx elt = XVECEXP (op, 0, i);
-
- if (GET_CODE (elt) != SET
- || GET_CODE (SET_DEST (elt)) != REG
- || GET_MODE (SET_DEST (elt)) != SImode
- || REGNO (SET_DEST (elt)) != (unsigned) (dest_regno + i)
- || GET_CODE (SET_SRC (elt)) != MEM
- || 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
- || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
- return 0;
- }
-
- return 1;
-}
-
-/* Similar, but tests for store multiple. */
-
-int
-mcore_store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- int count = XVECLEN (op, 0);
- int src_regno;
- rtx dest_addr;
- int i;
-
- /* Perform a quick check so we don't blow up below. */
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, 0)) != SET
- || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
- || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
- return 0;
-
- src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
- dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
-
- for (i = 1; i < count; i++)
- {
- rtx elt = XVECEXP (op, 0, i);
-
- if (GET_CODE (elt) != SET
- || GET_CODE (SET_SRC (elt)) != REG
- || GET_MODE (SET_SRC (elt)) != SImode
- || REGNO (SET_SRC (elt)) != (unsigned) (src_regno + i)
- || GET_CODE (SET_DEST (elt)) != MEM
- || 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_addr)
- || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
- || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
- return 0;
- }
-
- return 1;
-}
\f
/* ??? Block move stuff stolen from m88k. This code has not been
verified for correctness. */
static const enum machine_mode mode_from_align[] =
{
VOIDmode, QImode, HImode, VOIDmode, SImode,
- VOIDmode, VOIDmode, VOIDmode, DImode
};
static void
-block_move_sequence (rtx dest, rtx dst_mem, rtx src, rtx src_mem,
- int size, int align, int offset)
+block_move_sequence (rtx dst_mem, rtx src_mem, int size, int align)
{
rtx temp[2];
enum machine_mode mode[2];
int amount[2];
- int active[2];
+ bool active[2];
int phase = 0;
int next;
- int offset_ld = offset;
- int offset_st = offset;
-
- active[0] = active[1] = FALSE;
+ int offset_ld = 0;
+ int offset_st = 0;
+ rtx x;
- /* Establish parameters for the first load and for the second load if
- it is known to be the same mode as the first. */
- amount[0] = amount[1] = align;
-
- mode[0] = mode_from_align[align];
+ x = XEXP (dst_mem, 0);
+ if (!REG_P (x))
+ {
+ x = force_reg (Pmode, x);
+ dst_mem = replace_equiv_address (dst_mem, x);
+ }
- temp[0] = gen_reg_rtx (mode[0]);
-
- if (size >= 2 * align)
+ x = XEXP (src_mem, 0);
+ if (!REG_P (x))
{
- mode[1] = mode[0];
- temp[1] = gen_reg_rtx (mode[1]);
+ x = force_reg (Pmode, x);
+ src_mem = replace_equiv_address (src_mem, x);
}
+ active[0] = active[1] = false;
+
do
{
- rtx srcp, dstp;
-
next = phase;
- phase = !phase;
+ phase ^= 1;
if (size > 0)
{
- /* Change modes as the sequence tails off. */
- if (size < amount[next])
- {
- amount[next] = (size >= 4 ? 4 : (size >= 2 ? 2 : 1));
- mode[next] = mode_from_align[amount[next]];
- temp[next] = gen_reg_rtx (mode[next]);
- }
-
- size -= amount[next];
- srcp = gen_rtx_MEM (
-#if 0
- MEM_IN_STRUCT_P (src_mem) ? mode[next] : BLKmode,
-#else
- mode[next],
-#endif
- gen_rtx_PLUS (Pmode, src, GEN_INT (offset_ld)));
-
- RTX_UNCHANGING_P (srcp) = RTX_UNCHANGING_P (src_mem);
- MEM_VOLATILE_P (srcp) = MEM_VOLATILE_P (src_mem);
- MEM_IN_STRUCT_P (srcp) = 1;
- emit_insn (gen_rtx_SET (VOIDmode, temp[next], srcp));
- offset_ld += amount[next];
- active[next] = TRUE;
+ int next_amount;
+
+ next_amount = (size >= 4 ? 4 : (size >= 2 ? 2 : 1));
+ next_amount = MIN (next_amount, align);
+
+ amount[next] = next_amount;
+ mode[next] = mode_from_align[next_amount];
+ temp[next] = gen_reg_rtx (mode[next]);
+
+ x = adjust_address (src_mem, mode[next], offset_ld);
+ emit_insn (gen_rtx_SET (VOIDmode, temp[next], x));
+
+ offset_ld += next_amount;
+ size -= next_amount;
+ active[next] = true;
}
if (active[phase])
{
- active[phase] = FALSE;
+ active[phase] = false;
- dstp = gen_rtx_MEM (
-#if 0
- MEM_IN_STRUCT_P (dst_mem) ? mode[phase] : BLKmode,
-#else
- mode[phase],
-#endif
- gen_rtx_PLUS (Pmode, dest, GEN_INT (offset_st)));
-
- RTX_UNCHANGING_P (dstp) = RTX_UNCHANGING_P (dst_mem);
- MEM_VOLATILE_P (dstp) = MEM_VOLATILE_P (dst_mem);
- MEM_IN_STRUCT_P (dstp) = 1;
- emit_insn (gen_rtx_SET (VOIDmode, dstp, temp[phase]));
+ x = adjust_address (dst_mem, mode[phase], offset_st);
+ emit_insn (gen_rtx_SET (VOIDmode, x, temp[phase]));
+
offset_st += amount[phase];
}
}
while (active[next]);
}
-void
-mcore_expand_block_move (rtx dst_mem, rtx src_mem, rtx * operands)
+bool
+mcore_expand_block_move (rtx *operands)
{
- int align = INTVAL (operands[3]);
- int bytes;
+ HOST_WIDE_INT align, bytes, max;
+
+ if (GET_CODE (operands[2]) != CONST_INT)
+ return false;
+
+ bytes = INTVAL (operands[2]);
+ align = INTVAL (operands[3]);
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (bytes <= 0)
+ return false;
+ if (align > 4)
+ align = 4;
+
+ switch (align)
{
- bytes = INTVAL (operands[2]);
-
- if (bytes <= 0)
- return;
- if (align > 4)
- align = 4;
-
- /* RBE: bumped 1 and 2 byte align from 1 and 2 to 4 and 8 bytes before
- we give up and go to memcpy. */
- if ((align == 4 && (bytes <= 4*4
- || ((bytes & 01) == 0 && bytes <= 8*4)
- || ((bytes & 03) == 0 && bytes <= 16*4)))
- || (align == 2 && bytes <= 4*2)
- || (align == 1 && bytes <= 4*1))
- {
- block_move_sequence (operands[0], dst_mem, operands[1], src_mem,
- bytes, align, 0);
- return;
- }
+ case 4:
+ if (bytes & 1)
+ max = 4*4;
+ else if (bytes & 3)
+ max = 8*4;
+ else
+ max = 16*4;
+ break;
+ case 2:
+ max = 4*2;
+ break;
+ case 1:
+ max = 4*1;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (bytes <= max)
+ {
+ block_move_sequence (operands[0], operands[1], bytes, align);
+ return true;
}
- /* If we get here, just use the library routine. */
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "memcpy"), 0, VOIDmode, 3,
- operands[0], Pmode, operands[1], Pmode, operands[2],
- SImode);
+ return false;
}
\f
assert (growths <= MAX_STACK_GROWS);
for (i = 0; i < growths; i++)
- {
- if (infp->growth[i] % STACK_BYTES)
- {
- fprintf (stderr,"stack growth of %d is not %d aligned\n",
- infp->growth[i], STACK_BYTES);
- abort ();
- }
- }
+ gcc_assert (!(infp->growth[i] % STACK_BYTES));
}
/* Define the offset between two registers, one to be eliminated, and
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
return below_frame;
- abort ();
-
- return 0;
+ gcc_unreachable ();
}
/* Keep track of some information about varargs for the prolog. */
x = DECL_RTL (current_function_decl);
- if (GET_CODE (x) != MEM)
- abort ();
+ gcc_assert (GET_CODE (x) == MEM);
x = XEXP (x, 0);
- if (GET_CODE (x) != SYMBOL_REF)
- abort ();
+ gcc_assert (GET_CODE (x) == SYMBOL_REF);
if (mcore_current_function_name)
free (mcore_current_function_name);
/* The MCORE cannot load a large constant into a register, constants have to
come from a pc relative load. The reference of a pc relative load
- instruction must be less than 1k infront of the instruction. This
+ instruction must be less than 1k in front of the instruction. This
means that we often have to dump a constant inside a function, and
generate code to branch around it.
if (code != BARRIER && code != NOTE && !is_cond_candidate (insn))
return NEXT_INSN (insn);
- /* Remember the last real insn before the label (ie end of block 2). */
+ /* Remember the last real insn before the label (i.e. end of block 2). */
if (code == JUMP_INSN || code == INSN)
{
blk_size ++;
void
mcore_override_options (void)
{
- if (mcore_stack_increment_string)
- {
- mcore_stack_increment = atoi (mcore_stack_increment_string);
-
- if (mcore_stack_increment < 0
- || (mcore_stack_increment == 0
- && (mcore_stack_increment_string[0] != '0'
- || mcore_stack_increment_string[1] != 0)))
- error ("invalid option `-mstack-increment=%s'",
- mcore_stack_increment_string);
- }
-
/* Only the m340 supports little endian code. */
if (TARGET_LITTLE_END && ! TARGET_M340)
- target_flags |= M340_BIT;
+ target_flags |= MASK_M340;
}
\f
/* Compute the number of word sized registers needed to
{
int size;
- /* The MCore ABI defines that a structure whoes size is not a whole multiple
+ /* The MCore ABI defines that a structure whose size is not a whole multiple
of bytes is passed packed into registers (or spilled onto the stack if
not enough registers are available) with the last few bytes of the
structure being packed, left-justified, into the last register/stack slot.
{
int arg_reg;
- if (! named)
+ if (! named || mode == VOIDmode)
return 0;
if (targetm.calls.must_pass_in_stack (mode, type))
return 0;
}
-/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
- Returns the number of argument registers required to hold *part* of
- a parameter of machine mode MODE and type TYPE (which may be NULL if
+/* Returns the number of bytes of argument registers required to hold *part*
+ of a parameter of machine mode MODE and type TYPE (which may be NULL if
the type is not known). If the argument fits entirely in the argument
registers, or entirely on the stack, then 0 is returned. CUM is the
number of argument registers already used by earlier parameters to
the function. */
-int
-mcore_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
- tree type, int named)
+static int
+mcore_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, bool named)
{
- int reg = ROUND_REG (cum, mode);
+ int reg = ROUND_REG (*cum, mode);
if (named == 0)
return 0;
reg = NPARM_REGS - reg;
/* Return partially in registers and partially on the stack. */
- return reg;
+ return reg * UNITS_PER_WORD;
}
\f
/* Return nonzero if SYMBOL is marked as being dllexport'd. */
rtlname = XEXP (DECL_RTL (decl), 0);
- if (GET_CODE (rtlname) == SYMBOL_REF)
- oldname = XSTR (rtlname, 0);
- else if ( GET_CODE (rtlname) == MEM
- && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
- oldname = XSTR (XEXP (rtlname, 0), 0);
- else
- abort ();
+ if (GET_CODE (rtlname) == MEM)
+ rtlname = XEXP (rtlname, 0);
+ gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
+ oldname = XSTR (rtlname, 0);
if (mcore_dllexport_name_p (oldname))
return; /* Already done. */
rtlname = XEXP (DECL_RTL (decl), 0);
- if (GET_CODE (rtlname) == SYMBOL_REF)
- oldname = XSTR (rtlname, 0);
- else if ( GET_CODE (rtlname) == MEM
- && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
- oldname = XSTR (XEXP (rtlname, 0), 0);
- else
- abort ();
+ if (GET_CODE (rtlname) == MEM)
+ rtlname = XEXP (rtlname, 0);
+ gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
+ oldname = XSTR (rtlname, 0);
- if (mcore_dllexport_name_p (oldname))
- abort (); /* This shouldn't happen. */
- else if (mcore_dllimport_name_p (oldname))
+ gcc_assert (!mcore_dllexport_name_p (oldname));
+ if (mcore_dllimport_name_p (oldname))
return; /* Already done. */
/* ??? One can well ask why we're making these checks here,
&& !DECL_VIRTUAL_P (decl)
&& DECL_INITIAL (decl))
{
- error ("%Jinitialized variable '%D' is marked dllimport", decl, decl);
+ error ("initialized variable %q+D is marked dllimport", decl);
return;
}
}
else
{
- warning ("`%s' attribute only applies to functions",
+ warning (OPT_Wattributes, "%qs attribute only applies to functions",
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
#ifdef OBJECT_FORMAT_ELF
static void
-mcore_asm_named_section (const char *name, unsigned int flags ATTRIBUTE_UNUSED)
+mcore_asm_named_section (const char *name,
+ unsigned int flags ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
{
fprintf (asm_out_file, "\t.section %s\n", name);
}