-/* Subroutines used for code generation on the Mitsubishi M32R cpu.
+/* Subroutines used for code generation on the Renesas M32R cpu.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GCC.
+ This file is part of GCC.
-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)
-any later version.
+ 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) any later version.
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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. */
#include "config.h"
#include "system.h"
static bool m32r_rtx_costs (rtx, int, int, int *);
\f
/* Initialize the GCC target structure. */
-#undef TARGET_ATTRIBUTE_TABLE
+#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE m32r_attribute_table
-#undef TARGET_ASM_ALIGNED_HI_OP
+#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
-#undef TARGET_ASM_ALIGNED_SI_OP
+#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
-#undef TARGET_ASM_FUNCTION_PROLOGUE
+#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE m32r_output_function_prologue
-#undef TARGET_ASM_FUNCTION_EPILOGUE
+#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE m32r_output_function_epilogue
-#undef TARGET_ASM_FILE_START
+#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START m32r_file_start
-#undef TARGET_SCHED_ADJUST_COST
+#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST m32r_adjust_cost
-#undef TARGET_SCHED_ADJUST_PRIORITY
+#undef TARGET_SCHED_ADJUST_PRIORITY
#define TARGET_SCHED_ADJUST_PRIORITY m32r_adjust_priority
-#undef TARGET_SCHED_ISSUE_RATE
+#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE m32r_issue_rate
-#undef TARGET_SCHED_VARIABLE_ISSUE
+#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE m32r_variable_issue
-#undef TARGET_SCHED_INIT
+#undef TARGET_SCHED_INIT
#define TARGET_SCHED_INIT m32r_sched_init
-#undef TARGET_SCHED_REORDER
+#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER m32r_sched_reorder
-#undef TARGET_ENCODE_SECTION_INFO
+#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO m32r_encode_section_info
-#undef TARGET_IN_SMALL_DATA_P
+#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P m32r_in_small_data_p
-#undef TARGET_RTX_COSTS
+#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS m32r_rtx_costs
-#undef TARGET_ADDRESS_COST
+#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST hook_int_rtx_0
struct gcc_target targetm = TARGET_INITIALIZER;
/* Called by OVERRIDE_OPTIONS to initialize various things. */
void
-m32r_init ()
+m32r_init (void)
{
init_reg_tables ();
enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
static void
-init_reg_tables ()
+init_reg_tables (void)
{
int i;
medium: addresses use 32 bits, use bl to make calls
large: addresses use 32 bits, use seth/add3/jl to make calls
- Grep for MODEL in m32r.h for more info.
-*/
+ Grep for MODEL in m32r.h for more info. */
static tree small_ident1;
static tree small_ident2;
static tree large_ident2;
static void
-init_idents ()
+init_idents (void)
{
if (small_ident1 == 0)
{
/* Handle an "model" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-m32r_handle_model_attribute (node, name, args, flags, no_add_attrs)
- tree *node ATTRIBUTE_UNUSED;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+m32r_handle_model_attribute (tree *node ATTRIBUTE_UNUSED, tree name,
+ tree args, int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree arg;
*/
static void
-m32r_encode_section_info (decl, rtl, first)
- tree decl;
- rtx rtl;
- int first;
+m32r_encode_section_info (tree decl, rtx rtl, int first)
{
int extra_flags = 0;
tree model_attr;
the object doesn't fit the linker will give an error. */
static bool
-m32r_in_small_data_p (decl)
- tree decl;
+m32r_in_small_data_p (tree decl)
{
tree section;
/* Do anything needed before RTL is emitted for each function. */
void
-m32r_init_expanders ()
+m32r_init_expanders (void)
{
/* ??? At one point there was code here. The function is left in
to make it easy to experiment. */
/* Acceptable arguments to the call insn. */
int
-call_address_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_address_operand (rtx op, enum machine_mode mode)
{
return symbolic_operand (op, mode);
}
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
return 0;
/* Returns 1 if OP is a symbol reference. */
int
-symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
int
-small_data_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_data_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (! TARGET_SDATA_USE)
return 0;
/* Return 1 if OP is a symbol that can use 24 bit addressing. */
int
-addr24_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+addr24_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx sym;
/* Return 1 if OP is a symbol that needs 32 bit addressing. */
int
-addr32_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+addr32_operand (rtx op, enum machine_mode mode)
{
rtx sym;
/* Return 1 if OP is a function that can be called with the `bl' insn. */
int
-call26_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+call26_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == SYMBOL_REF)
return SYMBOL_REF_MODEL (op) != M32R_MODEL_LARGE;
/* Returns 1 if OP is an acceptable operand for seth/add3. */
int
-seth_add3_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+seth_add3_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == LABEL_REF)
/* Return true if OP is a signed 8 bit immediate value. */
int
-int8_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int8_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return 0;
useful in comparisons. */
int
-cmp_int16_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+cmp_int16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return 0;
/* Return true if OP is an unsigned 16 bit immediate value. */
int
-uint16_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+uint16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return 0;
/* Return true if OP is a register or signed 16 bit value. */
int
-reg_or_int16_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_int16_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
/* Return true if OP is a register or an unsigned 16 bit value. */
int
-reg_or_uint16_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_uint16_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
because that is special cased. */
int
-reg_or_eq_int16_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_eq_int16_operand (rtx op, enum machine_mode mode)
{
HOST_WIDE_INT value;
/* Return true if OP is a register or signed 16 bit value for compares. */
int
-reg_or_cmp_int16_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_cmp_int16_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
/* Return true if OP is a register or the constant 0. */
int
-reg_or_zero_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_zero_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
/* Return true if OP is a const_int requiring two instructions to load. */
int
-two_insn_const_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+two_insn_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return 0;
move source. */
int
-move_src_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_src_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
move source. */
int
-move_double_src_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_double_src_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
/* Return true if OP is an acceptable argument for a move destination. */
int
-move_dest_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_dest_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
It is used by the 'G' CONST_DOUBLE_OK_FOR_LETTER. */
int
-easy_di_const (op)
- rtx op;
+easy_di_const (rtx op)
{
rtx high_rtx, low_rtx;
HOST_WIDE_INT high, low;
It is used by the 'H' CONST_DOUBLE_OK_FOR_LETTER. */
int
-easy_df_const (op)
- rtx op;
+easy_df_const (rtx op)
{
REAL_VALUE_TYPE r;
long l[2];
/* Return 1 if OP is an EQ or NE comparison operator. */
int
-eqne_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+eqne_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
/* Return 1 if OP is a signed comparison operator. */
int
-signed_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+signed_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
This is used in insn length calcs. */
int
-memreg_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+memreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;
}
operation. */
int
-extend_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+extend_operand (rtx op, enum machine_mode mode)
{
rtx addr;
Allow const_int 0 as well, which is a placeholder for NOP slots. */
int
-small_insn_p (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_insn_p (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
return 1;
/* Return nonzero if the operand is an insn that is a large insn. */
int
-large_insn_p (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+large_insn_p (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (! INSN_P (op))
return 0;
in this function. */
int
-m32r_pass_by_reference (type)
- tree type;
+m32r_pass_by_reference (tree type)
{
int size = int_size_in_bytes (type);
than being subsumed into the following branch instruction. */
rtx
-gen_compare (code, x, y, need_compare)
- enum rtx_code code;
- rtx x, y;
- int need_compare;
+gen_compare (enum rtx_code code, rtx x, rtx y, int need_compare)
{
- enum rtx_code compare_code, branch_code;
+ enum rtx_code compare_code;
+ enum rtx_code branch_code;
rtx cc_reg = gen_rtx_REG (CCmode, CARRY_REGNUM);
int must_swap = 0;
{
case EQ:
if (GET_CODE (y) == CONST_INT
- && CMP_INT16_P (INTVAL (y)) /* reg equal to small const. */
+ && CMP_INT16_P (INTVAL (y)) /* Reg equal to small const. */
&& y != const0_rtx)
{
rtx tmp = gen_reg_rtx (SImode);
x = tmp;
y = const0_rtx;
}
- else if (CONSTANT_P (y)) /* reg equal to const. */
+ else if (CONSTANT_P (y)) /* Reg equal to const. */
{
rtx tmp = force_reg (GET_MODE (x), y);
y = tmp;
}
- if (register_operand (y, SImode) /* reg equal to reg. */
- || y == const0_rtx) /* req equal to zero. */
+ if (register_operand (y, SImode) /* Reg equal to reg. */
+ || y == const0_rtx) /* Reg equal to zero. */
{
emit_insn (gen_cmp_eqsi_insn (x, y));
if (register_operand (y, SImode)
|| (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))
{
- rtx tmp = gen_reg_rtx (SImode); /* reg compared to reg. */
+ rtx tmp = gen_reg_rtx (SImode); /* Reg compared to reg. */
switch (code)
{
if (register_operand (y, SImode)
|| (GET_CODE (y) == CONST_INT && CMP_INT16_P (INTVAL (y))))
{
- rtx tmp = gen_reg_rtx (SImode); /* reg (unsigned) compared to reg. */
+ rtx tmp = gen_reg_rtx (SImode); /* Reg (unsigned) compared to reg. */
switch (code)
{
}
else
{
- /* reg/reg equal comparison */
+ /* Reg/reg equal comparison. */
if (compare_code == EQ
&& register_operand (y, SImode))
return gen_rtx (code, CCmode, x, y);
- /* reg/zero signed comparison */
+ /* Reg/zero signed comparison. */
if ((compare_code == EQ || compare_code == LT)
&& y == const0_rtx)
return gen_rtx (code, CCmode, x, y);
- /* reg/smallconst equal comparison */
+ /* Reg/smallconst equal comparison. */
if (compare_code == EQ
&& GET_CODE (y) == CONST_INT
&& CMP_INT16_P (INTVAL (y)))
{
rtx tmp = gen_reg_rtx (SImode);
+
emit_insn (gen_cmp_ne_small_const_insn (tmp, x, y));
return gen_rtx (code, CCmode, tmp, const0_rtx);
}
- /* reg/const equal comparison */
+ /* Reg/const equal comparison. */
if (compare_code == EQ
&& CONSTANT_P (y))
{
rtx tmp = force_reg (GET_MODE (x), y);
+
return gen_rtx (code, CCmode, x, tmp);
}
}
/* Split a 2 word move (DI or DF) into component parts. */
rtx
-gen_split_move_double (operands)
- rtx operands[];
+gen_split_move_double (rtx operands[])
{
enum machine_mode mode = GET_MODE (operands[0]);
rtx dest = operands[0];
{
int dregno = REGNO (dest);
- /* reg = reg */
+ /* Reg = reg. */
if (GET_CODE (src) == REG)
{
int sregno = REGNO (src);
operand_subword (src, !reverse, TRUE, mode)));
}
- /* reg = constant */
+ /* Reg = constant. */
else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
{
rtx words[2];
words[1]));
}
- /* reg = mem */
+ /* Reg = mem. */
else if (GET_CODE (src) == MEM)
{
/* If the high-address word is used in the address, we must load it
adjust_address (src, SImode,
!reverse * UNITS_PER_WORD)));
}
-
else
abort ();
}
- /* mem = reg */
+ /* Mem = reg. */
/* We used to optimize loads from single registers as
st r1,r3; st r2,+r3
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
int
-function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named ATTRIBUTE_UNUSED)
{
int ret;
unsigned int size =
and mode MODE, and we rely on this fact. */
void
-m32r_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int *pretend_size;
- int no_rtl;
+m32r_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int *pretend_size, int no_rtl)
{
int first_anon_arg;
/* Implement `va_arg'. */
rtx
-m32r_va_arg (valist, type)
- tree valist, type;
+m32r_va_arg (tree valist, tree type)
{
HOST_WIDE_INT size, rsize;
tree t;
tree type_ptr, type_ptr_ptr;
/* Pass by reference. */
-
type_ptr = build_pointer_type (type);
type_ptr_ptr = build_pointer_type (type_ptr);
else
{
/* Pass by value. */
-
if (size < UNITS_PER_WORD)
{
/* Care for bigendian correction on the aligned address. */
}
\f
static int
-m32r_adjust_cost (insn, link, dep_insn, cost)
- rtx insn ATTRIBUTE_UNUSED;
- rtx link ATTRIBUTE_UNUSED;
- rtx dep_insn ATTRIBUTE_UNUSED;
- int cost;
+m32r_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link ATTRIBUTE_UNUSED,
+ rtx dep_insn ATTRIBUTE_UNUSED, int cost)
{
return cost;
}
/* Return true if INSN is real instruction bearing insn. */
static int
-m32r_is_insn (insn)
- rtx insn;
+m32r_is_insn (rtx insn)
{
return (INSN_P (insn)
&& GET_CODE (PATTERN (insn)) != USE
short instructions are scheduled ahead of the long ones. */
static int
-m32r_adjust_priority (insn, priority)
- rtx insn;
- int priority;
+m32r_adjust_priority (rtx insn, int priority)
{
if (m32r_is_insn (insn)
&& get_attr_insn_size (insn) != INSN_SIZE_SHORT)
/* Initialize for scheduling a group of instructions. */
static void
-m32r_sched_init (stream, verbose, max_ready)
- FILE * stream ATTRIBUTE_UNUSED;
- int verbose ATTRIBUTE_UNUSED;
- int max_ready ATTRIBUTE_UNUSED;
+m32r_sched_init (FILE * stream ATTRIBUTE_UNUSED,
+ int verbose ATTRIBUTE_UNUSED,
+ int max_ready ATTRIBUTE_UNUSED)
{
m32r_sched_odd_word_p = FALSE;
}
/* Reorder the schedulers priority list if needed */
static int
-m32r_sched_reorder (stream, verbose, ready, n_readyp, clock)
- FILE * stream;
- int verbose;
- rtx * ready;
- int *n_readyp;
- int clock ATTRIBUTE_UNUSED;
+m32r_sched_reorder (FILE * stream, int verbose, rtx * ready,
+ int *n_readyp, int clock ATTRIBUTE_UNUSED)
{
int n_ready = *n_readyp;
if (n_ready > 1)
{
- rtx * long_head = (rtx *) alloca (sizeof (rtx) * n_ready);
+ rtx * long_head = alloca (sizeof (rtx) * n_ready);
rtx * long_tail = long_head;
- rtx * short_head = (rtx *) alloca (sizeof (rtx) * n_ready);
+ rtx * short_head = alloca (sizeof (rtx) * n_ready);
rtx * short_tail = short_head;
- rtx * new_head = (rtx *) alloca (sizeof (rtx) * n_ready);
+ rtx * new_head = alloca (sizeof (rtx) * n_ready);
rtx * new_tail = new_head + (n_ready - 1);
int i;
}
/* If we are on an odd word, emit a single short instruction if
- we can */
+ we can. */
if (m32r_sched_odd_word_p && short_head != short_tail)
*new_tail-- = *short_head++;
- /* Now dump out all of the long instructions */
+ /* Now dump out all of the long instructions. */
while (long_head != long_tail)
*new_tail-- = *long_head++;
- /* Now dump out all of the short instructions */
+ /* Now dump out all of the short instructions. */
while (short_head != short_tail)
*new_tail-- = *short_head++;
- if (new_tail+1 != new_head)
+ if (new_tail + 1 != new_head)
abort ();
memcpy (ready, new_head, sizeof (rtx) * n_ready);
This is sort of a lie. The m32r can issue only 1 long insn at
once, but it can issue 2 short insns. The default therefore is
set at 2, but this can be overridden by the command line option
- -missue-rate=1 */
+ -missue-rate=1. */
+
static int
-m32r_issue_rate ()
+m32r_issue_rate (void)
{
return ((TARGET_LOW_ISSUE_RATE) ? 1 : 2);
}
/* If we have a machine that can issue a variable # of instructions
per cycle, indicate how many more instructions can be issued
after the current one. */
+
static int
-m32r_variable_issue (stream, verbose, insn, how_many)
- FILE * stream;
- int verbose;
- rtx insn;
- int how_many;
+m32r_variable_issue (FILE * stream, int verbose, rtx insn, int how_many)
{
int orig_odd_word_p = m32r_sched_odd_word_p;
int short_p = FALSE;
/* Cost functions. */
static bool
-m32r_rtx_costs (x, code, outer_code, total)
- rtx x;
- int code, outer_code ATTRIBUTE_UNUSED;
- int *total;
+m32r_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
{
switch (code)
{
case CONST_DOUBLE:
{
rtx high, low;
+
split_double (x, &high, &low);
*total = COSTS_N_INSNS (!INT16_P (INTVAL (high))
+ !INT16_P (INTVAL (low)));
call with DECL = NULL_TREE. */
enum m32r_function_type
-m32r_compute_function_type (decl)
- tree decl;
+m32r_compute_function_type (tree decl)
{
/* Cached value. */
static enum m32r_function_type fn_type = M32R_FUNCTION_UNKNOWN;
containing anonymous args separately but that complicates things too
much (so it's not done).
3) The return address is saved after the register save area so as to have as
- many insns as possible between the restoration of `lr' and the `jmp lr'.
-*/
+ many insns as possible between the restoration of `lr' and the `jmp lr'. */
/* Structure to be filled in by m32r_compute_frame_size with register
save masks, and offsets for the current function. */
struct m32r_frame_info
{
- unsigned int total_size; /* # bytes that the entire frame takes up */
- unsigned int extra_size; /* # bytes of extra stuff */
- unsigned int pretend_size; /* # bytes we push and pretend caller did */
- unsigned int args_size; /* # bytes that outgoing arguments take up */
- unsigned int reg_size; /* # bytes needed to store regs */
- unsigned int var_size; /* # bytes that variables take up */
- unsigned int gmask; /* mask of saved gp registers */
- unsigned int save_fp; /* nonzero if fp must be saved */
- unsigned int save_lr; /* nonzero if lr (return addr) must be saved */
- int initialized; /* nonzero if frame size already calculated */
+ unsigned int total_size; /* # bytes that the entire frame takes up. */
+ unsigned int extra_size; /* # bytes of extra stuff. */
+ unsigned int pretend_size; /* # bytes we push and pretend caller did. */
+ unsigned int args_size; /* # bytes that outgoing arguments take up. */
+ unsigned int reg_size; /* # bytes needed to store regs. */
+ unsigned int var_size; /* # bytes that variables take up. */
+ unsigned int gmask; /* Mask of saved gp registers. */
+ unsigned int save_fp; /* Nonzero if fp must be saved. */
+ unsigned int save_lr; /* Nonzero if lr (return addr) must be saved. */
+ int initialized; /* Nonzero if frame size already calculated. */
};
/* Current frame information calculated by m32r_compute_frame_size. */
static struct m32r_frame_info zero_frame_info;
#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
-#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
+#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
/* Tell prologue and epilogue if register REGNO should be saved / restored.
The return address and frame pointer are treated separately.
&& (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
#define MUST_SAVE_FRAME_POINTER (regs_ever_live[FRAME_POINTER_REGNUM])
-#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM] || current_function_profile)
+#define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM] || current_function_profile)
-#define SHORT_INSN_SIZE 2 /* size of small instructions */
-#define LONG_INSN_SIZE 4 /* size of long instructions */
+#define SHORT_INSN_SIZE 2 /* Size of small instructions. */
+#define LONG_INSN_SIZE 4 /* Size of long instructions. */
/* Return the bytes needed to compute the frame pointer from the current
stack pointer.
SIZE is the size needed for local variables. */
unsigned int
-m32r_compute_frame_size (size)
- int size; /* # of var. bytes allocated. */
+m32r_compute_frame_size (int size) /* # of var. bytes allocated. */
{
int regno;
unsigned int total_size, var_size, args_size, pretend_size, extra_size;
interrupt_p = M32R_INTERRUPT_P (fn_type);
/* Calculate space needed for registers. */
-
for (regno = 0; regno < M32R_MAX_INT_REGS; regno++)
{
if (MUST_SAVE_REGISTER (regno, interrupt_p))
function. If not specified, 0 is used. */
int
-m32r_first_insn_address ()
+m32r_first_insn_address (void)
{
if (! current_frame_info.initialized)
m32r_compute_frame_size (get_frame_size ());
/* Expand the m32r prologue as a series of insns. */
void
-m32r_expand_prologue ()
+m32r_expand_prologue (void)
{
int regno;
int frame_size;
}
/* Save any registers we need to and set up fp. */
-
if (current_frame_info.save_fp)
emit_insn (gen_movsi_push (stack_pointer_rtx, frame_pointer_rtx));
+ current_frame_info.reg_size));
if (frame_size == 0)
- ; /* nothing to do */
+ ; /* Nothing to do. */
else if (frame_size <= 32768)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-frame_size)));
else
{
rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
+
emit_insn (gen_movsi (tmp, GEN_INT (frame_size)));
emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
}
m32r_compute_frame_size which calculates the prolog size. */
static void
-m32r_output_function_prologue (file, size)
- FILE * file;
- HOST_WIDE_INT size;
+m32r_output_function_prologue (FILE * file, HOST_WIDE_INT size)
{
enum m32r_function_type fn_type = m32r_compute_function_type (current_function_decl);
/* If this is an interrupt handler, mark it as such. */
if (M32R_INTERRUPT_P (fn_type))
- {
- fprintf (file, "\t%s interrupt handler\n",
- ASM_COMMENT_START);
- }
+ fprintf (file, "\t%s interrupt handler\n", ASM_COMMENT_START);
if (! current_frame_info.initialized)
m32r_compute_frame_size (size);
and regs. */
static void
-m32r_output_function_epilogue (file, size)
- FILE * file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+m32r_output_function_epilogue (FILE * file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int regno;
int noepilogue = FALSE;
{
unsigned int reg_offset = var_size + args_size;
if (reg_offset == 0)
- ; /* nothing to do */
+ ; /* Nothing to do. */
else if (reg_offset < 128)
fprintf (file, "\taddi %s,%s%d\n",
sp_str, IMMEDIATE_PREFIX, reg_offset);
else if (frame_pointer_needed)
{
unsigned int reg_offset = var_size + args_size;
+
if (reg_offset == 0)
fprintf (file, "\tmv %s,%s\n", sp_str, fp_str);
else if (reg_offset < 32768)
fprintf (file, "\tjmp %s\n", reg_names[RETURN_ADDR_REGNUM]);
}
-#if 0 /* no longer needed */
- /* Ensure the function cleanly ends on a 32 bit boundary. */
- fprintf (file, "\t.fillinsn\n");
-#endif
-
/* Reset state info for each function. */
current_frame_info = zero_frame_info;
m32r_compute_function_type (NULL_TREE);
epilogue. */
int
-direct_return ()
+direct_return (void)
{
if (!reload_completed)
return FALSE;
}
\f
-/* PIC */
+/* PIC. */
/* Emit special PIC prologues and epilogues. */
void
-m32r_finalize_pic ()
+m32r_finalize_pic (void)
{
- /* nothing to do */
+ /* Nothing to do. */
}
\f
/* Nested function support. */
CXT is an RTX for the static chain value for the function. */
void
-m32r_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp ATTRIBUTE_UNUSED;
- rtx fnaddr ATTRIBUTE_UNUSED;
- rtx cxt ATTRIBUTE_UNUSED;
+m32r_initialize_trampoline (rtx tramp ATTRIBUTE_UNUSED,
+ rtx fnaddr ATTRIBUTE_UNUSED,
+ rtx cxt ATTRIBUTE_UNUSED)
{
}
\f
static void
-m32r_file_start ()
+m32r_file_start (void)
{
default_file_start ();
For `%' followed by punctuation, CODE is the punctuation and X is null. */
void
-m32r_print_operand (file, x, code)
- FILE * file;
- rtx x;
- int code;
+m32r_print_operand (FILE * file, rtx x, int code)
{
rtx addr;
output_operand_lossage ("invalid operand to %%R code");
return;
- case 'H' : /* High word */
- case 'L' : /* Low word */
+ case 'H' : /* High word. */
+ case 'L' : /* Low word. */
if (GET_CODE (x) == REG)
{
- /* L = least significant word, H = most significant word */
+ /* L = least significant word, H = most significant word. */
if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
fputs (reg_names[REGNO (x)], file);
else
return;
}
- case 'B' : /* Bottom half */
- case 'T' : /* Top half */
+ case 'B' : /* Bottom half. */
+ case 'T' : /* Top half. */
/* Output the argument to a `seth' insn (sets the Top half-word).
For constants output arguments to a seth/or3 pair to set Top and
Bottom halves. For symbols output arguments to a seth/add3 pair to
fputs (IMMEDIATE_PREFIX, file);
return;
-#if 0 /* ??? no longer used */
- case '@' :
- fputs (reg_names[SDA_REGNUM], file);
- return;
-#endif
-
case 0 :
/* Do nothing special. */
break;
/* Print a memory address as an operand to reference that memory location. */
void
-m32r_print_operand_address (file, addr)
- FILE * file;
- rtx addr;
+m32r_print_operand_address (FILE * file, rtx addr)
{
- register rtx base;
- register rtx index = 0;
- int offset = 0;
+ rtx base;
+ rtx index = 0;
+ int offset = 0;
switch (GET_CODE (addr))
{
fputs (reg_names[REGNO (XEXP (addr, 0))], file);
break;
- case PRE_INC : /* Assume SImode */
+ case PRE_INC : /* Assume SImode. */
fprintf (file, "+%s", reg_names[REGNO (XEXP (addr, 0))]);
break;
- case PRE_DEC : /* Assume SImode */
+ case PRE_DEC : /* Assume SImode. */
fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]);
break;
- case POST_INC : /* Assume SImode */
+ case POST_INC : /* Assume SImode. */
fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]);
break;
}
/* Return true if the operands are the constants 0 and 1. */
+
int
-zero_and_one (operand1, operand2)
- rtx operand1;
- rtx operand2;
+zero_and_one (rtx operand1, rtx operand2)
{
return
GET_CODE (operand1) == CONST_INT
}
/* Return nonzero if the operand is suitable for use in a conditional move sequence. */
+
int
-conditional_move_operand (operand, mode)
- rtx operand;
- enum machine_mode mode;
+conditional_move_operand (rtx operand, enum machine_mode mode)
{
- /* Only defined for simple integers so far... */
+ /* Only defined for simple integers so far... */
if (mode != SImode && mode != HImode && mode != QImode)
return FALSE;
}
}
-/* Return true if the code is a test of the carry bit */
+/* Return true if the code is a test of the carry bit. */
+
int
-carry_compare_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+carry_compare_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx x;
conditional_move_operand() function above. The destination is operand[0].
The condition is operand [1]. The 'true' value is operand [2] and the
'false' value is operand [3]. */
+
char *
-emit_cond_move (operands, insn)
- rtx * operands;
- rtx insn ATTRIBUTE_UNUSED;
+emit_cond_move (rtx * operands, rtx insn ATTRIBUTE_UNUSED)
{
static char buffer [100];
const char * dest = reg_names [REGNO (operands [0])];
/* Returns true if the registers contained in the two
rtl expressions are different. */
+
int
-m32r_not_same_reg (a, b)
- rtx a;
- rtx b;
+m32r_not_same_reg (rtx a, rtx b)
{
int reg_a = -1;
int reg_b = -2;
\f
/* Use a library function to move some bytes. */
+
static void
-block_move_call (dest_reg, src_reg, bytes_rtx)
- rtx dest_reg;
- rtx src_reg;
- rtx bytes_rtx;
+block_move_call (rtx dest, rtx src_reg, rtx bytes_rtx)
{
/* We want to pass the size as Pmode, which will normally be SImode
but will be DImode if we are using 64 bit longs and pointers. */
operands[3] is the alignment. */
void
-m32r_expand_block_move (operands)
- rtx operands[];
+m32r_expand_block_move (rtx operands[])
{
rtx orig_dst = operands[0];
rtx orig_src = operands[1];
operands[4] is a temp register. */
void
-m32r_output_block_move (insn, operands)
- rtx insn ATTRIBUTE_UNUSED;
- rtx operands[];
+m32r_output_block_move (rtx insn ATTRIBUTE_UNUSED, rtx operands[])
{
HOST_WIDE_INT bytes = INTVAL (operands[2]);
int first_time;
/* Return true if op is an integer constant, less than or equal to
MAX_MOVE_BYTES. */
+
int
-m32r_block_immediate_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+m32r_block_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT
|| INTVAL (op) > MAX_MOVE_BYTES
/* Return true if using NEW_REG in place of OLD_REG is ok. */
int
-m32r_hard_regno_rename_ok (old_reg, new_reg)
- unsigned int old_reg ATTRIBUTE_UNUSED;
- unsigned int new_reg;
+m32r_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
+ unsigned int new_reg)
{
/* Interrupt routines can't clobber any register that isn't already used. */
if (lookup_attribute ("interrupt", DECL_ATTRIBUTES (current_function_decl))