Add prototype header file

Import some code from Cygnus internal sources.

From-SVN: r30459
This commit is contained in:
Nick Clifton 1999-11-09 15:07:07 +00:00 committed by Nick Clifton
parent f1c7f59711
commit 56e2e7627e
5 changed files with 1974 additions and 694 deletions

View File

@ -1,3 +1,31 @@
Tue Nov 9 14:55:44 1999 Nick Clifton <nickc@cygnus.com>
* config/m32r/m32r-protos.h: New file: Prototypes for functions
defined in m32r.c
* config/m32r/m32r.h: Move prototypes to m32r-protos.h
Add support for subtargets.
Add prototypes for new predicates.
Add scheduling macros.
* config/m32r/m32r.c: Fix compile time warnings.
(int8_operand): New predicate function.
(reg_or_cmp_int16_operand): New predicate function.
(extend_operand): New predicate function.
(m32r_adjust_code): New scheduling function.
(m32r_adjust_priorty): New scheduling function.
(m32r_sched_init): New scheduling function.
(m32r_sched_reorder): New scheduling function.
(m32r_sched_variable_issue): New scheduling function.
(direct_return): New codegen function.
(m32r_not_same_reg): New rtl testsing function.
* config/m32r/m32r.md: Fix compile time warnings.
Add support for pre decrement and post increment memory
references.
Add S<cc> patterns.
Add fabs patterns.
Mon Nov 8 22:20:13 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* global.c (EXECUTE_IF_CONFLICT): Don't define.

View File

@ -0,0 +1,110 @@
/* Prototypes for m32r.c functions used in the md file & elsewhere.
Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Function prototypes that cannot exist in v850.h due to dependency
compilcations. */
#define Mmode enum machine_mode
extern void sbss_section PROTO ((void));
extern void sdata_section PROTO ((void));
extern void m32r_init PROTO ((void));
extern void m32r_init_expanders PROTO ((void));
extern unsigned m32r_compute_frame_size PROTO ((int));
extern int m32r_first_insn_address PROTO ((void));
extern void m32r_expand_prologue PROTO ((void));
extern void m32r_output_function_prologue PROTO ((FILE *, int));
extern void m32r_output_function_epilogue PROTO ((FILE *, int));
extern void m32r_finalize_pic PROTO ((void));
extern void m32r_asm_file_start PROTO ((FILE *));
extern void m32r_sched_init PROTO ((FILE *, int));
extern int direct_return PROTO ((void));
#ifdef TREE_CODE
extern int m32r_valid_machine_decl_attribute PROTO ((tree, tree, tree, tree));
extern int m32r_comp_type_attributes PROTO ((tree, tree));
extern void m32r_select_section PROTO ((tree, int));
extern void m32r_encode_section_info PROTO ((tree));
extern enum m32r_function_type m32r_compute_function_type PROTO ((tree));
extern void m32r_select_section PROTO ((tree, int));
extern void m32r_set_default_type_attributes PROTO ((tree));
#ifdef HAVE_MACHINE_MODES
extern void m32r_setup_incoming_varargs PROTO ((CUMULATIVE_ARGS *, Mmode, tree, int *, int));
extern int function_arg_partial_nregs PROTO ((CUMULATIVE_ARGS *, Mmode, tree, int));
#endif
#endif /* TREE_CODE */
#ifdef RTX_CODE
extern int easy_di_const PROTO ((rtx));
extern int easy_df_const PROTO ((rtx));
extern int m32r_select_cc_mode PROTO ((int, rtx, rtx));
extern rtx gen_compare PROTO ((enum rtx_code, rtx, rtx, int));
extern rtx gen_split_move_double PROTO ((rtx *));
extern int m32r_address_code PROTO ((rtx));
extern void m32r_initialize_trampoline PROTO ((rtx, rtx, rtx));
extern int zero_and_one PROTO ((rtx, rtx));
extern char * emit_cond_move PROTO ((rtx *, rtx));
extern char * m32r_output_block_move PROTO ((rtx, rtx *));
extern void m32r_expand_block_move PROTO ((rtx *));
extern void m32r_print_operand PROTO ((FILE *, rtx, int));
extern void m32r_print_operand_address PROTO ((FILE *, rtx));
extern int m32r_address_cost PROTO ((rtx));
extern int m32r_adjust_cost PROTO ((rtx, rtx, rtx, int));
extern int m32r_adjust_priority PROTO ((rtx, int));
extern void m32r_sched_reorder PROTO ((FILE *, int, rtx *, int));
extern int m32r_sched_variable_issue PROTO ((FILE *, int, rtx, int));
extern int m32r_not_same_reg PROTO ((rtx, rtx));
#ifdef HAVE_MACHINE_MODES
extern int call_address_operand PROTO ((rtx, Mmode));
extern int call_operand PROTO ((rtx, Mmode));
extern int symbolic_operand PROTO ((rtx, Mmode));
extern int small_data_operand PROTO ((rtx, Mmode));
extern int addr24_operand PROTO ((rtx, Mmode));
extern int addr32_operand PROTO ((rtx, Mmode));
extern int call26_operand PROTO ((rtx, Mmode));
extern int seth_add3_operand PROTO ((rtx, Mmode));
extern int cmp_int16_operand PROTO ((rtx, Mmode));
extern int uint16_operand PROTO ((rtx, Mmode));
extern int reg_or_int16_operand PROTO ((rtx, Mmode));
extern int reg_or_uint16_operand PROTO ((rtx, Mmode));
extern int reg_or_cmp_int16_operand PROTO ((rtx, Mmode));
extern int two_insn_const_operand PROTO ((rtx, Mmode));
extern int move_src_operand PROTO ((rtx, Mmode));
extern int move_double_src_operand PROTO ((rtx, Mmode));
extern int move_dest_operand PROTO ((rtx, Mmode));
extern int eqne_comparison_operator PROTO ((rtx, Mmode));
extern int signed_comparison_operator PROTO ((rtx, Mmode));
extern int memreg_operand PROTO ((rtx, Mmode));
extern int small_insn_p PROTO ((rtx, Mmode));
extern int large_insn_p PROTO ((rtx, Mmode));
extern int conditional_move_operand PROTO ((rtx, Mmode));
extern int carry_compare_operand PROTO ((rtx, Mmode));
extern int m32r_block_immediate_operand PROTO ((rtx, Mmode));
extern int extend_operand PROTO ((rtx, Mmode));
extern int reg_or_eq_int16_operand PROTO ((rtx, Mmode));
extern int int8_operand PROTO ((rtx, Mmode));
#endif /* HAVE_MACHINE_MODES */
#ifdef TREE_CODE
extern struct rtx_def * m32r_va_arg PROTO ((tree, tree));
#endif /* TREE_CODE */
#endif /* RTX_CODE */
#undef Mmode

View File

@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "recog.h"
#include "toplev.h"
#include "m32r-protos.h"
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
@ -44,16 +45,18 @@ rtx m32r_compare_op0, m32r_compare_op1;
char m32r_punct_chars[256];
/* Selected code model. */
char *m32r_model_string = M32R_MODEL_DEFAULT;
const char * m32r_model_string = M32R_MODEL_DEFAULT;
enum m32r_model m32r_model;
/* Selected SDA support. */
char *m32r_sdata_string = M32R_SDATA_DEFAULT;
const char * m32r_sdata_string = M32R_SDATA_DEFAULT;
enum m32r_sdata m32r_sdata;
/* Scheduler support */
int m32r_sched_odd_word_p;
/* Forward declaration. */
static void init_reg_tables PROTO((void));
static void init_reg_tables PROTO ((void));
/* Called by OVERRIDE_OPTIONS to initialize various things. */
@ -88,7 +91,6 @@ m32r_init ()
m32r_sdata = M32R_SDATA_USE;
else
error ("bad value (%s) for -msdata switch", m32r_sdata_string);
}
/* Vectors to keep interesting information about registers where it can easily
@ -104,7 +106,7 @@ enum m32r_mode_class
{
C_MODE,
S_MODE, D_MODE, T_MODE, O_MODE,
SF_MODE, DF_MODE, TF_MODE, OF_MODE
SF_MODE, DF_MODE, TF_MODE, OF_MODE, A_MODE
};
/* Modes for condition codes. */
@ -119,6 +121,8 @@ enum m32r_mode_class
/* Modes for quad-word and smaller quantities. */
#define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
/* Modes for accumulators. */
#define A_MODES (1 << (int) A_MODE)
/* Value is 1 if register/mode pair is acceptable on arc. */
@ -126,7 +130,7 @@ unsigned int m32r_hard_regno_mode_ok[FIRST_PSEUDO_REGISTER] =
{
T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, S_MODES, S_MODES, S_MODES,
S_MODES, C_MODES
S_MODES, C_MODES, A_MODES
};
unsigned int m32r_mode_class [NUM_MACHINE_MODES];
@ -451,23 +455,21 @@ m32r_init_expanders ()
/* Acceptable arguments to the call insn. */
int
call_address_operand (op, int_mode)
call_address_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
return symbolic_operand (op, int_mode);
return symbolic_operand (op, mode);
/* Constants and values in registers are not OK, because
the m32r BL instruction can only support PC relative branching. */
}
int
call_operand (op, int_mode)
call_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
if (GET_CODE (op) != MEM)
return 0;
op = XEXP (op, 0);
@ -477,9 +479,9 @@ call_operand (op, int_mode)
/* Returns 1 if OP is a symbol reference. */
int
symbolic_operand (op, int_mode)
symbolic_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
switch (GET_CODE (op))
{
@ -496,9 +498,9 @@ symbolic_operand (op, int_mode)
/* Return 1 if OP is a reference to an object in .sdata/.sbss. */
int
small_data_operand (op, int_mode)
small_data_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (! TARGET_SDATA_USE)
return 0;
@ -519,9 +521,9 @@ small_data_operand (op, int_mode)
/* Return 1 if OP is a symbol that can use 24 bit addressing. */
int
addr24_operand (op, int_mode)
addr24_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) == LABEL_REF)
return TARGET_ADDR24;
@ -551,24 +553,24 @@ addr24_operand (op, int_mode)
/* Return 1 if OP is a symbol that needs 32 bit addressing. */
int
addr32_operand (op, int_mode)
addr32_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
if (GET_CODE (op) == LABEL_REF)
return TARGET_ADDR32;
if (GET_CODE (op) == SYMBOL_REF)
return (! addr24_operand (op, int_mode)
&& ! small_data_operand (op, int_mode));
return (! addr24_operand (op, mode)
&& ! small_data_operand (op, mode));
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
{
return (! addr24_operand (op, int_mode)
&& ! small_data_operand (op, int_mode));
return (! addr24_operand (op, mode)
&& ! small_data_operand (op, mode));
}
return 0;
@ -577,9 +579,9 @@ addr32_operand (op, int_mode)
/* Return 1 if OP is a function that can be called with the `bl' insn. */
int
call26_operand (op, int_mode)
call26_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) == SYMBOL_REF)
return ! LARGE_NAME_P (XSTR (op, 0));
@ -590,9 +592,9 @@ call26_operand (op, int_mode)
/* Returns 1 if OP is an acceptable operand for seth/add3. */
int
seth_add3_operand (op, int_mode)
seth_add3_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == LABEL_REF)
@ -608,13 +610,25 @@ seth_add3_operand (op, int_mode)
return 0;
}
/* Return true if OP is a signed 8 bit immediate value. */
int
int8_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) != CONST_INT)
return 0;
return INT8_P (INTVAL (op));
}
/* Return true if OP is a signed 16 bit immediate value
useful in comparisons. */
int
cmp_int16_operand (op, int_mode)
cmp_int16_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) != CONST_INT)
return 0;
@ -624,24 +638,22 @@ cmp_int16_operand (op, int_mode)
/* Return true if OP is an unsigned 16 bit immediate value. */
int
uint16_operand (op, int_mode)
uint16_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) != CONST_INT)
return 0;
return UINT16_P (INTVAL (op));
}
/* Return true if OP is a register or signed 8 bit value. */
/* Return true if OP is a register or signed 16 bit value. */
int
reg_or_int16_operand (op, int_mode)
reg_or_int16_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
if (GET_CODE (op) != CONST_INT)
@ -652,12 +664,10 @@ reg_or_int16_operand (op, int_mode)
/* Return true if OP is a register or an unsigned 16 bit value. */
int
reg_or_uint16_operand (op, int_mode)
reg_or_uint16_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
if (GET_CODE (op) != CONST_INT)
@ -665,15 +675,35 @@ reg_or_uint16_operand (op, int_mode)
return UINT16_P (INTVAL (op));
}
/* Return true if OP is a register or an integer value that can be
used is SEQ/SNE. We can use either XOR of the value or ADD of
the negative of the value for the constant. Don't allow 0,
because that is special cased. */
int
reg_or_eq_int16_operand (op, mode)
rtx op;
enum machine_mode mode;
{
HOST_WIDE_INT value;
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
if (GET_CODE (op) != CONST_INT)
return 0;
value = INTVAL (op);
return (value != 0) && (UINT16_P (value) || CMP_INT16_P (-value));
}
/* Return true if OP is a register or signed 16 bit value for compares. */
int
reg_or_cmp_int16_operand (op, int_mode)
reg_or_cmp_int16_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
if (GET_CODE (op) == REG || GET_CODE (op) == SUBREG)
return register_operand (op, mode);
if (GET_CODE (op) != CONST_INT)
@ -684,9 +714,9 @@ reg_or_cmp_int16_operand (op, int_mode)
/* Return true if OP is a const_int requiring two instructions to load. */
int
two_insn_const_operand (op, int_mode)
two_insn_const_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) != CONST_INT)
return 0;
@ -701,16 +731,15 @@ two_insn_const_operand (op, int_mode)
move source. */
int
move_src_operand (op, int_mode)
move_src_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
switch (GET_CODE (op))
{
case SYMBOL_REF :
case CONST :
return addr24_operand (op, int_mode);
return addr24_operand (op, mode);
case CONST_INT :
/* ??? We allow more cse opportunities if we only allow constants
loadable with one insn, and split the rest into two. The instances
@ -743,6 +772,9 @@ move_src_operand (op, int_mode)
else
return register_operand (op, mode);
case MEM :
if (GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == PRE_DEC)
return 0; /* loads can't do pre-{inc,dec} */
return address_operand (XEXP (op, 0), mode);
default :
return 0;
@ -753,11 +785,10 @@ move_src_operand (op, int_mode)
move source. */
int
move_double_src_operand (op, int_mode)
move_double_src_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
switch (GET_CODE (op))
{
case CONST_INT :
@ -769,7 +800,7 @@ move_double_src_operand (op, int_mode)
/* (subreg (mem ...) ...) can occur here if the inner part was once a
pseudo-reg and is now a stack slot. */
if (GET_CODE (SUBREG_REG (op)) == MEM)
return move_double_src_operand (SUBREG_REG (op), int_mode);
return move_double_src_operand (SUBREG_REG (op), mode);
else
return register_operand (op, mode);
case MEM :
@ -786,11 +817,10 @@ move_double_src_operand (op, int_mode)
/* Return true if OP is an acceptable argument for a move destination. */
int
move_dest_operand (op, int_mode)
move_dest_operand (op, mode)
rtx op;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
switch (GET_CODE (op))
{
case REG :
@ -803,6 +833,8 @@ move_dest_operand (op, int_mode)
else
return register_operand (op, mode);
case MEM :
if (GET_CODE (XEXP (op, 0)) == POST_INC)
return 0; /* stores can't do post inc */
return address_operand (XEXP (op, 0), mode);
default :
return 0;
@ -853,9 +885,9 @@ easy_df_const (op)
/* Return 1 if OP is an EQ or NE comparison operator. */
int
eqne_comparison_operator (op, int_mode)
eqne_comparison_operator (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
enum rtx_code code = GET_CODE (op);
@ -867,9 +899,9 @@ eqne_comparison_operator (op, int_mode)
/* Return 1 if OP is a signed comparison operator. */
int
signed_comparison_operator (op, int_mode)
signed_comparison_operator (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
enum rtx_code code = GET_CODE (op);
@ -883,20 +915,48 @@ signed_comparison_operator (op, int_mode)
This is used in insn length calcs. */
int
memreg_operand (op, int_mode)
memreg_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG;
}
/* Return true if OP is an acceptable input argument for a zero/sign extend
operation. */
int
extend_operand (op, mode)
rtx op;
enum machine_mode mode;
{
rtx addr;
switch (GET_CODE (op))
{
case REG :
case SUBREG :
return register_operand (op, mode);
case MEM :
addr = XEXP (op, 0);
if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
return 0; /* loads can't do pre inc/pre dec */
return address_operand (addr, mode);
default :
return 0;
}
}
/* Return non-zero if the operand is an insn that is a small insn.
Allow const_int 0 as well, which is a placeholder for NOP slots. */
int
small_insn_p (op, int_mode)
small_insn_p (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
return 1;
@ -910,9 +970,9 @@ small_insn_p (op, int_mode)
/* Return non-zero if the operand is an insn that is a large insn. */
int
large_insn_p (op, int_mode)
large_insn_p (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_RTX_CLASS (GET_CODE (op)) != 'i')
return 0;
@ -932,13 +992,13 @@ m32r_select_cc_mode (op, x, y)
rtx x ATTRIBUTE_UNUSED;
rtx y ATTRIBUTE_UNUSED;
{
return (int)SImode;
return (int) CCmode;
}
/* X and Y are two things to compare using CODE. Emit the compare insn and
return the rtx for compare [arg0 of the if_then_else].
If need_compare is true then the comparison insn must be generated, rather
than being susummed into the following branch instruction. */
than being susummed into the following branch instruction. */
rtx
gen_compare (code, x, y, need_compare)
@ -965,7 +1025,7 @@ gen_compare (code, x, y, need_compare)
case GEU: compare_code = LTU; branch_code = EQ; break;
default:
abort();
abort ();
}
if (need_compare)
@ -992,7 +1052,7 @@ gen_compare (code, x, y, need_compare)
if (register_operand (y, SImode) /* reg equal to reg. */
|| y == const0_rtx) /* req equal to zero. */
{
emit_insn (gen_cmp_eqsi_insn (x, y));
emit_insn (gen_cmp_eqsi_insn (x, y));
return gen_rtx (code, mode, cc_reg, const0_rtx);
}
@ -1031,7 +1091,7 @@ gen_compare (code, x, y, need_compare)
code = NE;
break;
default:
abort();
abort ();
}
return gen_rtx (code, mode, cc_reg, const0_rtx);
@ -1083,7 +1143,6 @@ gen_compare (code, x, y, need_compare)
}
}
else
if (! TARGET_OLD_COMPARE)
{
/* reg/reg equal comparison */
if (compare_code == EQ
@ -1280,13 +1339,12 @@ gen_split_move_double (operands)
/* Implements the FUNCTION_ARG_PARTIAL_NREGS macro. */
int
function_arg_partial_nregs (cum, int_mode, type, named)
function_arg_partial_nregs (cum, mode, type, named)
CUMULATIVE_ARGS *cum;
int int_mode;
enum machine_mode mode;
tree type;
int named ATTRIBUTE_UNUSED;
{
enum machine_mode mode = (enum machine_mode)int_mode;
int ret;
int size = (((mode == BLKmode && type)
? int_size_in_bytes (type)
@ -1310,14 +1368,13 @@ function_arg_partial_nregs (cum, int_mode, type, named)
and mode MODE, and we rely on this fact. */
void
m32r_setup_incoming_varargs (cum, int_mode, type, pretend_size, no_rtl)
m32r_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
CUMULATIVE_ARGS *cum;
int int_mode;
enum machine_mode mode;
tree type;
int *pretend_size;
int no_rtl;
{
enum machine_mode mode = (enum machine_mode)int_mode;
int first_anon_arg;
if (no_rtl)
@ -1353,6 +1410,7 @@ m32r_setup_incoming_varargs (cum, int_mode, type, pretend_size, no_rtl)
}
}
/* Implement `va_arg'. */
rtx
@ -1415,6 +1473,218 @@ m32r_va_arg (valist, type)
return addr_rtx;
}
int
m32r_adjust_cost (insn, link, dep_insn, cost)
rtx insn ATTRIBUTE_UNUSED;
rtx link ATTRIBUTE_UNUSED;
rtx dep_insn ATTRIBUTE_UNUSED;
int cost;
{
return cost;
}
/* A C statement (sans semicolon) to update the integer scheduling
priority `INSN_PRIORITY(INSN)'. Reduce the priority to execute
the INSN earlier, increase the priority to execute INSN later.
Do not define this macro if you do not need to adjust the
scheduling priorities of insns.
On the m32r, increase the priority of long instructions so that
the short instructions are scheduled ahead of the long ones. */
int
m32r_adjust_priority (insn, priority)
rtx insn;
int priority;
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
enum rtx_code code = GET_CODE (PATTERN (insn));
if (code != USE && code != CLOBBER && code != ADDR_VEC
&& get_attr_insn_size (insn) != INSN_SIZE_SHORT)
priority <<= 3;
}
return priority;
}
/* Initialize for scheduling a group of instructions. */
void
m32r_sched_init (stream, verbose)
FILE * stream ATTRIBUTE_UNUSED;
int verbose ATTRIBUTE_UNUSED;
{
m32r_sched_odd_word_p = FALSE;
}
/* Reorder the schedulers priority list if needed */
void
m32r_sched_reorder (stream, verbose, ready, n_ready)
FILE * stream;
int verbose;
rtx * ready;
int n_ready;
{
if (TARGET_DEBUG)
return;
if (verbose <= 7)
stream = (FILE *)0;
if (stream)
fprintf (stream,
";;\t\t::: Looking at %d insn(s) on ready list, boundary is %s word\n",
n_ready,
(m32r_sched_odd_word_p) ? "odd" : "even");
if (n_ready > 1)
{
rtx * long_head = (rtx *) alloca (sizeof (rtx) * n_ready);
rtx * long_tail = long_head;
rtx * short_head = (rtx *) alloca (sizeof (rtx) * n_ready);
rtx * short_tail = short_head;
rtx * new_head = (rtx *) alloca (sizeof (rtx) * n_ready);
rtx * new_tail = new_head + (n_ready - 1);
int i;
/* Loop through the instructions, classifing them as short/long. Try
to keep 2 short together and/or 1 long. Note, the ready list is
actually ordered backwards, so keep it in that manner. */
for (i = n_ready-1; i >= 0; i--)
{
rtx insn = ready[i];
enum rtx_code code;
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
|| (code = GET_CODE (PATTERN (insn))) == USE
|| code == CLOBBER || code == ADDR_VEC)
{
/* Dump all current short/long insns just in case */
while (long_head != long_tail)
*new_tail-- = *long_head++;
while (short_head != short_tail)
*new_tail-- = *short_head++;
*new_tail-- = insn;
if (stream)
fprintf (stream,
";;\t\t::: Skipping non instruction %d\n",
INSN_UID (insn));
}
else
{
if (get_attr_insn_size (insn) != INSN_SIZE_SHORT)
*long_tail++ = insn;
else
*short_tail++ = insn;
}
}
/* If we are on an odd word, emit a single short instruction if
we can */
if (m32r_sched_odd_word_p && short_head != short_tail)
*new_tail-- = *short_head++;
/* 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 */
while (short_head != short_tail)
*new_tail-- = *short_head++;
if (new_tail+1 != new_head)
abort ();
bcopy ((char *) new_head, (char *) ready, sizeof (rtx) * n_ready);
if (stream)
{
#ifdef HAIFA
fprintf (stream, ";;\t\t::: New ready list: ");
debug_ready_list (ready, n_ready);
#else
int i;
for (i = 0; i < n_ready; i++)
{
rtx insn = ready[i];
enum rtx_code code;
fprintf (stream, " %d", INSN_UID (ready[i]));
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
|| (code = GET_CODE (PATTERN (insn))) == USE
|| code == CLOBBER || code == ADDR_VEC)
fputs ("(?)", stream);
else if (get_attr_insn_size (insn) != INSN_SIZE_SHORT)
fputs ("(l)", stream);
else
fputs ("(s)", stream);
}
fprintf (stream, "\n");
#endif
}
}
}
/* 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. */
int
m32r_sched_variable_issue (stream, verbose, insn, how_many)
FILE * stream;
int verbose;
rtx insn;
int how_many;
{
int orig_odd_word_p = m32r_sched_odd_word_p;
int short_p = FALSE;
how_many--;
if (how_many > 0 && !TARGET_DEBUG)
{
if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
how_many++;
else if (GET_CODE (PATTERN (insn)) == USE
|| GET_CODE (PATTERN (insn)) == CLOBBER
|| GET_CODE (PATTERN (insn)) == ADDR_VEC)
how_many++;
else if (get_attr_insn_size (insn) != INSN_SIZE_SHORT)
{
how_many = 0;
m32r_sched_odd_word_p = 0;
}
else
{
m32r_sched_odd_word_p = !m32r_sched_odd_word_p;
short_p = TRUE;
}
}
if (verbose > 7 && stream)
fprintf (stream,
";;\t\t::: %s insn %d starts on an %s word, can emit %d more instruction(s)\n",
short_p ? "short" : "long",
INSN_UID (insn),
orig_odd_word_p ? "odd" : "even",
how_many);
return how_many;
}
/* Cost functions. */
/* Provide the costs of an addressing mode that contains ADDR.
@ -1638,7 +1908,7 @@ m32r_expand_prologue ()
{
int regno;
int frame_size;
unsigned int gmask = current_frame_info.gmask;
unsigned int gmask;
if (! current_frame_info.initialized)
m32r_compute_frame_size (get_frame_size ());
@ -1848,6 +2118,22 @@ m32r_output_function_epilogue (file, size)
current_frame_info = zero_frame_info;
m32r_compute_function_type (NULL_TREE);
}
/* Return non-zero if this function is known to have a null or 1 instruction
epilogue. */
int
direct_return ()
{
if (!reload_completed)
return FALSE;
if (! current_frame_info.initialized)
m32r_compute_frame_size (get_frame_size ());
return current_frame_info.total_size == 0;
}
/* PIC */
@ -1968,7 +2254,7 @@ m32r_print_operand (file, x, code)
if (GET_CODE (x) != CONST_DOUBLE
|| GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
abort ();
fatal_insn ("Bad insn for 'A'", x);
REAL_VALUE_FROM_CONST_DOUBLE (d, x);
REAL_VALUE_TO_DECIMAL (d, "%.20e", str);
fprintf (file, "%s", str);
@ -2088,21 +2374,21 @@ m32r_print_operand (file, x, code)
if (GET_CODE (addr) == PRE_INC)
{
if (GET_CODE (XEXP (addr, 0)) != REG)
abort ();
fatal_insn ("Pre-increment address is not a register", x);
fprintf (file, "@+%s", reg_names[REGNO (XEXP (addr, 0))]);
}
else if (GET_CODE (addr) == PRE_DEC)
{
if (GET_CODE (XEXP (addr, 0)) != REG)
abort ();
fatal_insn ("Pre-decrement address is not a register", x);
fprintf (file, "@-%s", reg_names[REGNO (XEXP (addr, 0))]);
}
else if (GET_CODE (addr) == POST_INC)
{
if (GET_CODE (XEXP (addr, 0)) != REG)
abort ();
fatal_insn ("Post-increment address is not a register", x);
fprintf (file, "@%s+", reg_names[REGNO (XEXP (addr, 0))]);
}
@ -2180,7 +2466,7 @@ m32r_print_operand_address (file, addr)
fputs (reg_names[REGNO (base)], file);
}
else
abort ();
fatal_insn ("Bad address", addr);
}
else if (GET_CODE (base) == LO_SUM)
{
@ -2196,12 +2482,12 @@ m32r_print_operand_address (file, addr)
fputs (reg_names[REGNO (XEXP (base, 0))], file);
}
else
abort ();
fatal_insn ("Bad address", addr);
break;
case LO_SUM :
if (GET_CODE (XEXP (addr, 0)) != REG)
abort ();
fatal_insn ("Lo_sum not of register", addr);
if (small_data_operand (XEXP (addr, 1), VOIDmode))
fputs ("sda(", file);
else
@ -2244,12 +2530,10 @@ zero_and_one (operand1, operand2)
/* Return non-zero if the operand is suitable for use in a conditional move sequence. */
int
conditional_move_operand (operand, int_mode)
conditional_move_operand (operand, mode)
rtx operand;
int int_mode;
enum machine_mode mode;
{
enum machine_mode mode = (enum machine_mode)int_mode;
/* Only defined for simple integers so far... */
if (mode != SImode && mode != HImode && mode != QImode)
return FALSE;
@ -2276,13 +2560,13 @@ conditional_move_operand (operand, int_mode)
/* Return true if the code is a test of the carry bit */
int
carry_compare_operand (op, int_mode)
carry_compare_operand (op, mode)
rtx op;
int int_mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
rtx x;
if (GET_MODE (op) != SImode && GET_MODE (op) != VOIDmode)
if (GET_MODE (op) != CCmode && GET_MODE (op) != VOIDmode)
return FALSE;
if (GET_CODE (op) != NE && GET_CODE (op) != EQ)
@ -2299,7 +2583,6 @@ carry_compare_operand (op, int_mode)
return TRUE;
}
/* Generate the correct assembler code to handle the conditional loading of a
value into a register. It is known that the operands satisfy the
conditional_move_operand() function above. The destination is operand[0].
@ -2341,6 +2624,30 @@ emit_cond_move (operands, insn)
return buffer;
}
/* Returns true if the registers contained in the two
rtl expressions are different. */
int
m32r_not_same_reg (a, b)
rtx a;
rtx b;
{
int reg_a = -1;
int reg_b = -2;
while (GET_CODE (a) == SUBREG)
a = SUBREG_REG (a);
if (GET_CODE (a) == REG)
reg_a = REGNO (a);
while (GET_CODE (b) == SUBREG)
b = SUBREG_REG (b);
if (GET_CODE (b) == REG)
reg_b = REGNO (b);
return reg_a != reg_b;
}
/* Use a library function to move some bytes. */
@ -2600,7 +2907,7 @@ m32r_output_block_move (insn, operands)
int
m32r_block_immediate_operand (op, mode)
rtx op;
int mode ATTRIBUTE_UNUSED;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
if (GET_CODE (op) != CONST_INT
|| INTVAL (op) > MAX_MOVE_BYTES

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff