mn10300.h (CONSTANT_ALIGNMENT): Define.

* config/mn10300/mn10300.h (CONSTANT_ALIGNMENT): Define.
        (DATA_ALIGNMENT, LOCAL_ALIGNMENT): Define.
        (FIRST_PSEUDO_REGISTER): Increase by one.
        (FIXED_REGISTERS, CALL_USED_REGISTERS): Update with CC_REG.
        (HARD_REGNO_MODE_OK): Call mn10300_hard_regno_mode_ok.
        (MODES_TIEABLE): Call mn10300_modes_tieable.
        (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add
        CC_REGS.
        (LEGITIMATE_CONSTANT_P): Call mn10300_legitimate_constant_p.
        (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY, NOTICE_UPDATE_CC)
        (SELECT_CC_MODE, REVERSIBLE_CC_MODE): Delete.
        (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Add CC register.
        (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Delete.
        (mn10300_cc_status_mdep): Delete.
        (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Delete.
        * config/mn10300/mn10300 (mn10300_option_override): Stop disabling
        the combine-stack-adjust pass.
        (print_operand): Use the mode of the comparison operation to
        select the comparison suffix.
        (notice_update_cc): Delete.
        (mn10300_secondary_reload_class): Remove test for stack pointer
        based arithmetic.
        (output_tst): Rename to mn10300_output_cmp.
        (impossible_plus_operand): Move into predicates.md.
        (mn10300_legitimize_address): Make static.
        (mn10300_legitimate_address_p): Make static.  Only allow SI sized
        constant pic operands.
        (mn10300_legitimate_constant_p): New function.
        (mn10300_case_values_threshold): Make static.
        (mn10300_hard_regno_mode_ok): New function.
        (mn10300_modes_tieable): New function.
        (mn10300_select_cc_mode): New function.
        * config/mn10300/predicates.md (impossible_plus_operand): Define.
        * config/mn10300/mn10300-protos.h: Tidy.
        (mn10300_legitimate_constant_p, mn10300_modes_tieable)
        (mn10300_hard_regno_mode_ok, mn10300_select_cc_mode): Prototype.
        * config/mn10300/mn10300.md (cc attribute): Delete.  Replace
        with clobbers or sets of CC_REG.
        (CC_REG): Define.
        (mov*): Remove use of CLR instruction.
        (cbranch_si4_<code>): New pattern/split.
        (integer_conditional_branch): New pattern.
        (cbranch_sf4_<code>): New pattern/split.
        (float_conditional_branch): New pattern.
        (casesi): Use addsi3 pattern instead of movsi pattern to add and
        move a value at the same time.
        (cc0 peepholes): Remove.

From-SVN: r165459
This commit is contained in:
Nick Clifton 2010-10-14 09:12:50 +00:00 committed by Nick Clifton
parent 6203e21acb
commit 4af476d7f2
6 changed files with 1081 additions and 837 deletions

View File

@ -1,3 +1,53 @@
2010-10-14 Nick Clifton <nickc@redhat.com>
* config/mn10300/mn10300.h (CONSTANT_ALIGNMENT): Define.
(DATA_ALIGNMENT, LOCAL_ALIGNMENT): Define.
(FIRST_PSEUDO_REGISTER): Increase by one.
(FIXED_REGISTERS, CALL_USED_REGISTERS): Update with CC_REG.
(HARD_REGNO_MODE_OK): Call mn10300_hard_regno_mode_ok.
(MODES_TIEABLE): Call mn10300_modes_tieable.
(REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add
CC_REGS.
(LEGITIMATE_CONSTANT_P): Call mn10300_legitimate_constant_p.
(CC_OVERFLOW_UNUSABLE, CC_NO_CARRY, NOTICE_UPDATE_CC)
(SELECT_CC_MODE, REVERSIBLE_CC_MODE): Delete.
(REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Add CC register.
(ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Delete.
(mn10300_cc_status_mdep): Delete.
(CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Delete.
* config/mn10300/mn10300 (mn10300_option_override): Stop disabling
the combine-stack-adjust pass.
(print_operand): Use the mode of the comparison operation to
select the comparison suffix.
(notice_update_cc): Delete.
(mn10300_secondary_reload_class): Remove test for stack pointer
based arithmetic.
(output_tst): Rename to mn10300_output_cmp.
(impossible_plus_operand): Move into predicates.md.
(mn10300_legitimize_address): Make static.
(mn10300_legitimate_address_p): Make static. Only allow SI sized
constant pic operands.
(mn10300_legitimate_constant_p): New function.
(mn10300_case_values_threshold): Make static.
(mn10300_hard_regno_mode_ok): New function.
(mn10300_modes_tieable): New function.
(mn10300_select_cc_mode): New function.
* config/mn10300/predicates.md (impossible_plus_operand): Define.
* config/mn10300/mn10300-protos.h: Tidy.
(mn10300_legitimate_constant_p, mn10300_modes_tieable)
(mn10300_hard_regno_mode_ok, mn10300_select_cc_mode): Prototype.
* config/mn10300/mn10300.md (cc attribute): Delete. Replace
with clobbers or sets of CC_REG.
(CC_REG): Define.
(mov*): Remove use of CLR instruction.
(cbranch_si4_<code>): New pattern/split.
(integer_conditional_branch): New pattern.
(cbranch_sf4_<code>): New pattern/split.
(float_conditional_branch): New pattern.
(casesi): Use addsi3 pattern instead of movsi pattern to add and
move a value at the same time.
(cc0 peepholes): Remove.
2010-10-14 Andrey Belevantsev <abel@ispras.ru> 2010-10-14 Andrey Belevantsev <abel@ispras.ru>
* sel-sched-ir.c (init_global_and_expr_for_insn): Set CANT_MOVE * sel-sched-ir.c (init_global_and_expr_for_insn): Set CANT_MOVE

View File

@ -19,35 +19,40 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#define Mmode enum machine_mode
#define Cstar const char *
#define Rclas enum reg_class
#ifdef RTX_CODE #ifdef RTX_CODE
extern rtx legitimize_pic_address (rtx, rtx);
extern rtx legitimize_pic_address (rtx, rtx); extern int legitimate_pic_operand_p (rtx);
extern int legitimate_pic_operand_p (rtx); extern bool mn10300_function_value_regno_p (const unsigned int);
extern void print_operand (FILE *, rtx, int); extern void mn10300_gen_multiple_store (int);
extern void print_operand_address (FILE *, rtx); extern int mn10300_get_live_callee_saved_regs (void);
extern void mn10300_print_reg_list (FILE *, int); extern bool mn10300_hard_regno_mode_ok (unsigned int, Mmode);
extern int mn10300_get_live_callee_saved_regs (void); extern bool mn10300_legitimate_constant_p (rtx);
extern void mn10300_gen_multiple_store (int); extern bool mn10300_modes_tieable (Mmode, Mmode);
extern void notice_update_cc (rtx, rtx); extern Cstar mn10300_output_cmp (rtx, rtx);
extern enum reg_class mn10300_secondary_reload_class (enum reg_class, extern void mn10300_print_reg_list (FILE *, int);
enum machine_mode, rtx); extern Rclas mn10300_secondary_reload_class (Rclas, Mmode, rtx);
extern const char *output_tst (rtx, rtx); extern Mmode mn10300_select_cc_mode (rtx);
extern int store_multiple_operation (rtx, enum machine_mode); extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]);
extern int symbolic_operand (rtx, enum machine_mode); extern void print_operand (FILE *, rtx, int);
extern int impossible_plus_operand (rtx, enum machine_mode); extern void print_operand_address (FILE *, rtx);
extern int store_multiple_operation (rtx, Mmode);
extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]); extern int symbolic_operand (rtx, Mmode);
extern bool mn10300_function_value_regno_p (const unsigned int);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
#ifdef TREE_CODE #ifdef TREE_CODE
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
enum machine_mode, tree, int);
#endif /* TREE_CODE */ #endif /* TREE_CODE */
extern void expand_prologue (void); extern int can_use_return_insn (void);
extern void expand_epilogue (void); extern void expand_prologue (void);
extern int initial_offset (int, int); extern void expand_epilogue (void);
extern int can_use_return_insn (void); extern int initial_offset (int, int);
extern int mask_ok_for_mem_btst (int, int); extern int mask_ok_for_mem_btst (int, int);
#undef Mmode
#undef Cstar
#undef Rclas

View File

@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h" #include "tm_p.h"
#include "target.h" #include "target.h"
#include "target-def.h" #include "target-def.h"
#include "df.h"
/* This is used by GOTaddr2picreg to uniquely identify /* This is used by GOTaddr2picreg to uniquely identify
UNSPEC_INT_LABELs. */ UNSPEC_INT_LABELs. */
@ -190,12 +191,6 @@ mn10300_option_override (void)
{ {
if (TARGET_AM33) if (TARGET_AM33)
target_flags &= ~MASK_MULT_BUG; target_flags &= ~MASK_MULT_BUG;
/* FIXME: The combine stack adjustments pass is breaking
cc0-setter/cc0-user relationship by inserting a jump
instruction. This should be investigated, but for now
just disable the pass. */
flag_combine_stack_adjustments = 0;
} }
static void static void
@ -220,7 +215,7 @@ print_operand (FILE *file, rtx x, int code)
{ {
case 'b': case 'b':
case 'B': case 'B':
if (cc_status.mdep.fpCC) if (GET_MODE (XEXP (x, 0)) == CC_FLOATmode)
{ {
switch (code == 'b' ? GET_CODE (x) switch (code == 'b' ? GET_CODE (x)
: reverse_condition_maybe_unordered (GET_CODE (x))) : reverse_condition_maybe_unordered (GET_CODE (x)))
@ -1008,7 +1003,7 @@ expand_epilogue (void)
/* SIZE includes the fixed stack space needed for function calls. */ /* SIZE includes the fixed stack space needed for function calls. */
size = get_frame_size () + crtl->outgoing_args_size; size = get_frame_size () + crtl->outgoing_args_size;
size += (crtl->outgoing_args_size ? 4 : 0); size += (crtl->outgoing_args_size ? 4 : 0);
if (TARGET_AM33_2 && fp_regs_to_save ()) if (TARGET_AM33_2 && fp_regs_to_save ())
{ {
int num_regs_to_save = fp_regs_to_save (), i; int num_regs_to_save = fp_regs_to_save (), i;
@ -1236,59 +1231,6 @@ expand_epilogue (void)
emit_jump_insn (gen_return_internal ()); emit_jump_insn (gen_return_internal ());
} }
/* Update the condition code from the insn. */
void
notice_update_cc (rtx body, rtx insn)
{
switch (get_attr_cc (insn))
{
case CC_NONE:
/* Insn does not affect CC at all. */
break;
case CC_NONE_0HIT:
/* Insn does not change CC, but the 0'th operand has been changed. */
if (cc_status.value1 != 0
&& reg_overlap_mentioned_p (recog_data.operand[0], cc_status.value1))
cc_status.value1 = 0;
break;
case CC_SET_ZN:
/* Insn sets the Z,N flags of CC to recog_data.operand[0].
V,C are unusable. */
CC_STATUS_INIT;
cc_status.flags |= CC_NO_CARRY | CC_OVERFLOW_UNUSABLE;
cc_status.value1 = recog_data.operand[0];
break;
case CC_SET_ZNV:
/* Insn sets the Z,N,V flags of CC to recog_data.operand[0].
C is unusable. */
CC_STATUS_INIT;
cc_status.flags |= CC_NO_CARRY;
cc_status.value1 = recog_data.operand[0];
break;
case CC_COMPARE:
/* The insn is a compare instruction. */
CC_STATUS_INIT;
cc_status.value1 = SET_SRC (body);
if (GET_CODE (SET_SRC (body)) == COMPARE
&& GET_MODE (XEXP (SET_SRC (body), 0)) == SFmode)
cc_status.mdep.fpCC = 1;
break;
case CC_CLOBBER:
/* Insn doesn't leave CC in a usable state. */
CC_STATUS_INIT;
break;
default:
gcc_unreachable ();
}
}
/* Recognize the PARALLEL rtx generated by mn10300_gen_multiple_store(). /* Recognize the PARALLEL rtx generated by mn10300_gen_multiple_store().
This function is for MATCH_PARALLEL and so assumes OP is known to be This function is for MATCH_PARALLEL and so assumes OP is known to be
parallel. If OP is a multiple store, return a mask indicating which parallel. If OP is a multiple store, return a mask indicating which
@ -1413,11 +1355,6 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
|| XEXP (in, 1) == stack_pointer_rtx)))) || XEXP (in, 1) == stack_pointer_rtx))))
return ADDRESS_REGS; return ADDRESS_REGS;
if (GET_CODE (in) == PLUS
&& (XEXP (in, 0) == stack_pointer_rtx
|| XEXP (in, 1) == stack_pointer_rtx))
return GENERAL_REGS;
if (TARGET_AM33_2 if (TARGET_AM33_2
&& rclass == FP_REGS) && rclass == FP_REGS)
{ {
@ -1425,7 +1362,7 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
constant address. */ constant address. */
if (GET_CODE (in) == MEM if (GET_CODE (in) == MEM
&& CONSTANT_ADDRESS_P (XEXP (in, 0))) && CONSTANT_ADDRESS_P (XEXP (in, 0)))
return (TARGET_AM33 ? DATA_OR_EXTENDED_REGS : DATA_REGS); return DATA_OR_EXTENDED_REGS;
/* Handle case were a pseudo may not get a hard register /* Handle case were a pseudo may not get a hard register
but has an equivalent memory location defined. */ but has an equivalent memory location defined. */
@ -1433,7 +1370,7 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
&& REGNO (inner) >= FIRST_PSEUDO_REGISTER && REGNO (inner) >= FIRST_PSEUDO_REGISTER
&& reg_equiv_mem [REGNO (inner)] && reg_equiv_mem [REGNO (inner)]
&& CONSTANT_ADDRESS_P (XEXP (reg_equiv_mem [REGNO (inner)], 0))) && CONSTANT_ADDRESS_P (XEXP (reg_equiv_mem [REGNO (inner)], 0)))
return (TARGET_AM33 ? DATA_OR_EXTENDED_REGS : DATA_REGS); return DATA_OR_EXTENDED_REGS;
} }
/* Otherwise assume no secondary reloads are needed. */ /* Otherwise assume no secondary reloads are needed. */
@ -1696,9 +1633,10 @@ mn10300_function_value_regno_p (const unsigned int regno)
return (regno == FIRST_DATA_REGNUM || regno == FIRST_ADDRESS_REGNUM); return (regno == FIRST_DATA_REGNUM || regno == FIRST_ADDRESS_REGNUM);
} }
/* Output a tst insn. */ /* Output a compare insn. */
const char * const char *
output_tst (rtx operand, rtx insn) mn10300_output_cmp (rtx operand, rtx insn)
{ {
rtx temp; rtx temp;
int past_call = 0; int past_call = 0;
@ -1786,19 +1724,6 @@ output_tst (rtx operand, rtx insn)
return "cmp 0,%0"; return "cmp 0,%0";
} }
int
impossible_plus_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != PLUS)
return 0;
if (XEXP (op, 0) == stack_pointer_rtx
|| XEXP (op, 1) == stack_pointer_rtx)
return 1;
return 0;
}
/* Similarly, but when using a zero_extract pattern for a btst where /* Similarly, but when using a zero_extract pattern for a btst where
the source operand might end up in memory. */ the source operand might end up in memory. */
int int
@ -1853,7 +1778,7 @@ symbolic_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
But on a few ports with segmented architectures and indexed addressing But on a few ports with segmented architectures and indexed addressing
(mn10300, hppa) it is used to rewrite certain problematical addresses. */ (mn10300, hppa) it is used to rewrite certain problematical addresses. */
rtx static rtx
mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED) enum machine_mode mode ATTRIBUTE_UNUSED)
{ {
@ -1941,7 +1866,7 @@ legitimate_pic_operand_p (rtx x)
{ {
if (fmt[i] == 'E') if (fmt[i] == 'E')
{ {
register int j; int j;
for (j = XVECLEN (x, i) - 1; j >= 0; j--) for (j = XVECLEN (x, i) - 1; j >= 0; j--)
if (! legitimate_pic_operand_p (XVECEXP (x, i, j))) if (! legitimate_pic_operand_p (XVECEXP (x, i, j)))
@ -1968,7 +1893,7 @@ legitimate_pic_operand_p (rtx x)
workaround and solution, see the comments in pa.c before the workaround and solution, see the comments in pa.c before the
function record_unscaled_index_insn_codes. */ function record_unscaled_index_insn_codes. */
bool static bool
mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{ {
if (CONSTANT_ADDRESS_P (x) if (CONSTANT_ADDRESS_P (x)
@ -2009,7 +1934,8 @@ mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
if (GET_CODE (index) == CONST if (GET_CODE (index) == CONST
&& GET_CODE (XEXP (index, 0)) != PLUS && GET_CODE (XEXP (index, 0)) != PLUS
&& (! flag_pic && (! flag_pic
|| legitimate_pic_operand_p (index))) || (legitimate_pic_operand_p (index)
&& GET_MODE_SIZE (mode) == 4)))
return TRUE; return TRUE;
} }
} }
@ -2017,6 +1943,55 @@ mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
return FALSE; return FALSE;
} }
/* Used by LEGITIMATE_CONSTANT_P(). Returns TRUE if X is a valid
constant. Note that some "constants" aren't valid, such as TLS
symbols and unconverted GOT-based references, so we eliminate
those here. */
bool
mn10300_legitimate_constant_p (rtx x)
{
switch (GET_CODE (x))
{
case CONST:
x = XEXP (x, 0);
if (GET_CODE (x) == PLUS)
{
if (GET_CODE (XEXP (x, 1)) != CONST_INT)
return false;
x = XEXP (x, 0);
}
/* Only some unspecs are valid as "constants". */
if (GET_CODE (x) == UNSPEC)
{
rtx sym = XVECEXP (x, 0, 0);
switch (XINT (x, 1))
{
case UNSPEC_INT_LABEL:
case UNSPEC_PIC:
case UNSPEC_GOT:
case UNSPEC_GOTOFF:
case UNSPEC_PLT:
return true;
default:
return false;
}
}
/* We must have drilled down to a symbol. */
if (!symbolic_operand (x, Pmode))
return false;
break;
default:
break;
}
return true;
}
static int static int
mn10300_address_cost_1 (rtx x, int *unsig) mn10300_address_cost_1 (rtx x, int *unsig)
{ {
@ -2215,7 +2190,8 @@ mn10300_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
were solely optimizing for space, but we keep it "reasonable" to avoid were solely optimizing for space, but we keep it "reasonable" to avoid
serious code efficiency lossage. */ serious code efficiency lossage. */
unsigned int mn10300_case_values_threshold (void) static unsigned int
mn10300_case_values_threshold (void)
{ {
return 6; return 6;
} }
@ -2310,3 +2286,48 @@ mn10300_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED,
{ {
return true; return true;
} }
bool
mn10300_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
{
if (REGNO_REG_CLASS (regno) == FP_REGS
|| REGNO_REG_CLASS (regno) == FP_ACC_REGS)
/* Do not store integer values in FP registers. */
return GET_MODE_CLASS (mode) == MODE_FLOAT && ((regno & 1) == 0);
if (((regno) & 1) == 0 || GET_MODE_SIZE (mode) == 4)
return true;
if (REGNO_REG_CLASS (regno) == DATA_REGS
|| (TARGET_AM33 && REGNO_REG_CLASS (regno) == ADDRESS_REGS)
|| REGNO_REG_CLASS (regno) == EXTENDED_REGS)
return GET_MODE_SIZE (mode) <= 4;
return false;
}
bool
mn10300_modes_tieable (enum machine_mode mode1, enum machine_mode mode2)
{
if (GET_MODE_CLASS (mode1) == MODE_FLOAT
&& GET_MODE_CLASS (mode2) != MODE_FLOAT)
return false;
if (GET_MODE_CLASS (mode2) == MODE_FLOAT
&& GET_MODE_CLASS (mode1) != MODE_FLOAT)
return false;
if (TARGET_AM33
|| mode1 == mode2
|| (GET_MODE_SIZE (mode1) <= 4 && GET_MODE_SIZE (mode2) <= 4))
return true;
return false;
}
enum machine_mode
mn10300_select_cc_mode (rtx x)
{
return (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) ? CC_FLOATmode : CCmode;
}

View File

@ -117,28 +117,32 @@ extern enum processor_type mn10300_processor;
All registers that the compiler knows about must be given numbers, All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers. */ even those that are not normally considered general registers. */
#define FIRST_PSEUDO_REGISTER 51 #define FIRST_PSEUDO_REGISTER 52
/* Specify machine-specific register numbers. */ /* Specify machine-specific register numbers. The commented out entries
#define FIRST_DATA_REGNUM 0 are defined in mn10300.md. */
#define LAST_DATA_REGNUM 3 #define FIRST_DATA_REGNUM 0
#define FIRST_ADDRESS_REGNUM 4 #define LAST_DATA_REGNUM 3
#define LAST_ADDRESS_REGNUM 8 #define FIRST_ADDRESS_REGNUM 4
/* #define PIC_REG 6 */
#define LAST_ADDRESS_REGNUM 8
/* #define SP_REG 9 */
#define FIRST_EXTENDED_REGNUM 10 #define FIRST_EXTENDED_REGNUM 10
#define LAST_EXTENDED_REGNUM 17 #define LAST_EXTENDED_REGNUM 17
#define FIRST_FP_REGNUM 18 #define FIRST_FP_REGNUM 18
#define LAST_FP_REGNUM 49 #define LAST_FP_REGNUM 49
#define MDR_REGNUM 50 #define MDR_REGNUM 50
#define FIRST_ARGUMENT_REGNUM 0 /* #define CC_REG 51 */
#define FIRST_ARGUMENT_REGNUM 0
/* Specify the registers used for certain standard purposes. /* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */ The values of these macros are register numbers. */
/* Register to use for pushing function arguments. */ /* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM+1) #define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
/* Base register for access to local variables of the function. */ /* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM-1) #define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM - 1)
/* Base register for access to arguments of the function. This /* Base register for access to arguments of the function. This
is a fake register and will be eliminated into either the frame is a fake register and will be eliminated into either the frame
@ -146,15 +150,15 @@ extern enum processor_type mn10300_processor;
#define ARG_POINTER_REGNUM LAST_ADDRESS_REGNUM #define ARG_POINTER_REGNUM LAST_ADDRESS_REGNUM
/* Register in which static-chain is passed to a function. */ /* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM+1) #define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
/* 1 for registers that have pervasive standard uses /* 1 for registers that have pervasive standard uses
and are not available for the register allocator. */ and are not available for the register allocator. */
#define FIXED_REGISTERS \ #define FIXED_REGISTERS \
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 \ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 \
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 \ , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 \
} }
/* 1 for registers not available across function calls. /* 1 for registers not available across function calls.
@ -167,8 +171,8 @@ extern enum processor_type mn10300_processor;
#define CALL_USED_REGISTERS \ #define CALL_USED_REGISTERS \
{ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 \ { 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 \
, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \ , 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 \
, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \ , 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
} }
/* Note: The definition of CALL_REALLY_USED_REGISTERS is not /* Note: The definition of CALL_REALLY_USED_REGISTERS is not
@ -181,7 +185,7 @@ extern enum processor_type mn10300_processor;
#define REG_ALLOC_ORDER \ #define REG_ALLOC_ORDER \
{ 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9 \ { 0, 1, 4, 5, 2, 3, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 8, 9 \
, 42, 43, 44, 45, 46, 47, 48, 49, 34, 35, 36, 37, 38, 39, 40, 41 \ , 42, 43, 44, 45, 46, 47, 48, 49, 34, 35, 36, 37, 38, 39, 40, 41 \
, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 \ , 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 51 \
} }
#define CONDITIONAL_REGISTER_USAGE \ #define CONDITIONAL_REGISTER_USAGE \
@ -197,8 +201,7 @@ extern enum processor_type mn10300_processor;
if (!TARGET_AM33_2) \ if (!TARGET_AM33_2) \
{ \ { \
for (i = FIRST_FP_REGNUM; \ for (i = FIRST_FP_REGNUM; \
i <= LAST_FP_REGNUM; \ i <= LAST_FP_REGNUM; i++) \
i++) \
fixed_regs[i] = call_used_regs[i] = 1; \ fixed_regs[i] = call_used_regs[i] = 1; \
} \ } \
if (flag_pic) \ if (flag_pic) \
@ -217,22 +220,15 @@ extern enum processor_type mn10300_processor;
/* Value is 1 if hard register REGNO can hold a value of machine-mode /* Value is 1 if hard register REGNO can hold a value of machine-mode
MODE. */ MODE. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
((REGNO_REG_CLASS (REGNO) == DATA_REGS \ mn10300_hard_regno_mode_ok ((REGNO), (MODE))
|| (TARGET_AM33 && REGNO_REG_CLASS (REGNO) == ADDRESS_REGS) \
|| REGNO_REG_CLASS (REGNO) == EXTENDED_REGS) \
? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4 \
: ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4)
/* Value is 1 if it is a good idea to tie two pseudo registers /* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2. when one has mode MODE1 and one has mode MODE2.
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
for any hard reg, then this must be 0 for correct output. */ for any hard reg, then this must be 0 for correct output. */
#define MODES_TIEABLE_P(MODE1, MODE2) \ #define MODES_TIEABLE_P(MODE1, MODE2) \
(TARGET_AM33 \ mn10300_modes_tieable ((MODE1), (MODE2))
|| MODE1 == MODE2 \
|| (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
/* 4 data, and effectively 3 address registers is small as far as I'm /* 4 data, and effectively 3 address registers is small as far as I'm
concerned. */ concerned. */
@ -263,7 +259,7 @@ enum reg_class {
DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS, DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS,
EXTENDED_REGS, DATA_OR_EXTENDED_REGS, ADDRESS_OR_EXTENDED_REGS, EXTENDED_REGS, DATA_OR_EXTENDED_REGS, ADDRESS_OR_EXTENDED_REGS,
SP_OR_EXTENDED_REGS, SP_OR_ADDRESS_OR_EXTENDED_REGS, SP_OR_EXTENDED_REGS, SP_OR_ADDRESS_OR_EXTENDED_REGS,
FP_REGS, FP_ACC_REGS, FP_REGS, FP_ACC_REGS, CC_REGS,
GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES
}; };
@ -271,35 +267,36 @@ enum reg_class {
/* Give names of register classes as strings for dump file. */ /* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \ #define REG_CLASS_NAMES \
{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \ { "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
"SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \ "SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
"EXTENDED_REGS", \ "EXTENDED_REGS", \
"DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \ "DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
"SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \ "SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
"FP_REGS", "FP_ACC_REGS", \ "FP_REGS", "FP_ACC_REGS", "CC_REGS", \
"GENERAL_REGS", "ALL_REGS", "LIM_REGS" } "GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
/* Define which registers fit in which classes. /* Define which registers fit in which classes.
This is an initializer for a vector of HARD_REG_SET This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */ of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \ #define REG_CLASS_CONTENTS \
{ { 0, 0 }, /* No regs */ \ { { 0, 0 }, /* No regs */ \
{ 0x0000f, 0 }, /* DATA_REGS */ \ { 0x0000000f, 0 }, /* DATA_REGS */ \
{ 0x001f0, 0 }, /* ADDRESS_REGS */ \ { 0x000001f0, 0 }, /* ADDRESS_REGS */ \
{ 0x00200, 0 }, /* SP_REGS */ \ { 0x00000200, 0 }, /* SP_REGS */ \
{ 0x001ff, 0 }, /* DATA_OR_ADDRESS_REGS */\ { 0x000001ff, 0 }, /* DATA_OR_ADDRESS_REGS */ \
{ 0x003f0, 0 }, /* SP_OR_ADDRESS_REGS */\ { 0x000003f0, 0 }, /* SP_OR_ADDRESS_REGS */ \
{ 0x3fc00, 0 }, /* EXTENDED_REGS */ \ { 0x0003fc00, 0 }, /* EXTENDED_REGS */ \
{ 0x3fc0f, 0 }, /* DATA_OR_EXTENDED_REGS */ \ { 0x0003fc0f, 0 }, /* DATA_OR_EXTENDED_REGS */ \
{ 0x3fdf0, 0 }, /* ADDRESS_OR_EXTENDED_REGS */ \ { 0x0003fdf0, 0 }, /* ADDRESS_OR_EXTENDED_REGS */ \
{ 0x3fe00, 0 }, /* SP_OR_EXTENDED_REGS */ \ { 0x0003fe00, 0 }, /* SP_OR_EXTENDED_REGS */ \
{ 0x3fff0, 0 }, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \ { 0x0003fff0, 0 }, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
{ 0xfffc0000, 0x3ffff }, /* FP_REGS */ \ { 0xfffc0000, 0x3ffff },/* FP_REGS */ \
{ 0x03fc0000, 0 }, /* FP_ACC_REGS */ \ { 0x03fc0000, 0 }, /* FP_ACC_REGS */ \
{ 0x3fdff, 0 }, /* GENERAL_REGS */ \ { 0x00000000, 0x80000 },/* CC_REGS */ \
{ 0xffffffff, 0x7ffff } /* ALL_REGS */ \ { 0x0003fdff, 0 }, /* GENERAL_REGS */ \
{ 0xffffffff, 0xfffff } /* ALL_REGS */ \
} }
/* The following macro defines cover classes for Integrated Register /* The following macro defines cover classes for Integrated Register
@ -326,6 +323,7 @@ enum reg_class {
(REGNO) == STACK_POINTER_REGNUM ? SP_REGS : \ (REGNO) == STACK_POINTER_REGNUM ? SP_REGS : \
(REGNO) <= LAST_EXTENDED_REGNUM ? EXTENDED_REGS : \ (REGNO) <= LAST_EXTENDED_REGNUM ? EXTENDED_REGS : \
(REGNO) <= LAST_FP_REGNUM ? FP_REGS : \ (REGNO) <= LAST_FP_REGNUM ? FP_REGS : \
(REGNO) == CC_REG ? CC_REGS : \
NO_REGS) NO_REGS)
/* The class value for index registers, and the one for base regs. */ /* The class value for index registers, and the one for base regs. */
@ -496,10 +494,11 @@ enum reg_class {
#define REG_PARM_STACK_SPACE(DECL) 8 #define REG_PARM_STACK_SPACE(DECL) 8
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
#define ACCUMULATE_OUTGOING_ARGS 1 #define ACCUMULATE_OUTGOING_ARGS 1
#if 1
/* So we can allocate space for return pointers once for the function /* So we can allocate space for return pointers once for the function
instead of around every call. */ instead of around every call. */
#define STACK_POINTER_OFFSET 4 #define STACK_POINTER_OFFSET 4
#endif
/* 1 if N is a possible register number for function argument passing. /* 1 if N is a possible register number for function argument passing.
On the MN10300, d0 and d1 are used in this way. */ On the MN10300, d0 and d1 are used in this way. */
@ -611,8 +610,7 @@ struct cum_arg {int nbytes; };
/* Nonzero if the constant value X is a legitimate general operand. /* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
#define LEGITIMATE_CONSTANT_P(X) mn10300_legitimate_constant_p (X)
#define LEGITIMATE_CONSTANT_P(X) 1
/* Zero if this needs fixing up to become PIC. */ /* Zero if this needs fixing up to become PIC. */
@ -675,20 +673,9 @@ struct cum_arg {int nbytes; };
goto FAIL; \ goto FAIL; \
while (0) while (0)
/* Tell final.c how to eliminate redundant test instructions. */ #define SELECT_CC_MODE(OP, X, Y) mn10300_select_cc_mode (X)
#define REVERSIBLE_CC_MODE(MODE) 0
/* Here we define machine-dependent flags and fields in cc_status
(see `conditions.h'). No extra ones are needed for the VAX. */
/* Store in cc_status the expressions
that the condition codes will describe
after execution of an instruction whose pattern is EXP.
Do not alter them if the instruction would not alter the cc's. */
#define CC_OVERFLOW_UNUSABLE 0x200
#define CC_NO_CARRY CC_NO_OVERFLOW
#define NOTICE_UPDATE_CC(EXP, INSN) notice_update_cc(EXP, INSN)
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \ #define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\ ((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\
((CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS) && \ ((CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS) && \
@ -762,24 +749,26 @@ struct cum_arg {int nbytes; };
/* How to refer to registers in assembler output. /* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */ This sequence is indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \ #define REGISTER_NAMES \
{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \ { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" \ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" \
, "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" \ , "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" \
, "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15" \ , "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15" \
, "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23" \ , "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23" \
, "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31", "mdr" \ , "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31" \
, "mdr", "EPSW" \
} }
#define ADDITIONAL_REGISTER_NAMES \ #define ADDITIONAL_REGISTER_NAMES \
{ {"r8", 4}, {"r9", 5}, {"r10", 6}, {"r11", 7}, \ { {"r8", 4}, {"r9", 5}, {"r10", 6}, {"r11", 7}, \
{"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3}, \ {"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3}, \
{"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13}, \ {"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13}, \
{"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17} \ {"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17} \
, {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24} \ , {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24} \
, {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32} \ , {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32} \
, {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40} \ , {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40} \
, {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48} \ , {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48} \
, {"cc", CC_REG} \
} }
/* Print an instruction operand X on file FILE. /* Print an instruction operand X on file FILE.
@ -792,9 +781,6 @@ struct cum_arg {int nbytes; };
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
#define ASM_OUTPUT_REG_POP(FILE,REGNO)
/* This is how to output an element of a case-vector that is absolute. */ /* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
@ -883,12 +869,3 @@ struct cum_arg {int nbytes; };
#define FILE_ASM_OP "\t.file\n" #define FILE_ASM_OP "\t.file\n"
typedef struct mn10300_cc_status_mdep
{
int fpCC;
}
cc_status_mdep;
#define CC_STATUS_MDEP cc_status_mdep
#define CC_STATUS_MDEP_INIT (cc_status.mdep.fpCC = 0)

File diff suppressed because it is too large Load Diff

View File

@ -47,3 +47,10 @@
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG); return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
}) })
(define_predicate "impossible_plus_operand"
(match_code "plus")
{
return XEXP (op, 0) == stack_pointer_rtx
|| XEXP (op, 1) == stack_pointer_rtx;
})