mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
6203e21acb
commit
4af476d7f2
|
@ -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>
|
||||
|
||||
* sel-sched-ir.c (init_global_and_expr_for_insn): Set CANT_MOVE
|
||||
|
|
|
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#define Mmode enum machine_mode
|
||||
#define Cstar const char *
|
||||
#define Rclas enum reg_class
|
||||
|
||||
#ifdef RTX_CODE
|
||||
|
||||
extern rtx legitimize_pic_address (rtx, rtx);
|
||||
extern int legitimate_pic_operand_p (rtx);
|
||||
extern void print_operand (FILE *, rtx, int);
|
||||
extern void print_operand_address (FILE *, rtx);
|
||||
extern void mn10300_print_reg_list (FILE *, int);
|
||||
extern int mn10300_get_live_callee_saved_regs (void);
|
||||
extern void mn10300_gen_multiple_store (int);
|
||||
extern void notice_update_cc (rtx, rtx);
|
||||
extern enum reg_class mn10300_secondary_reload_class (enum reg_class,
|
||||
enum machine_mode, rtx);
|
||||
extern const char *output_tst (rtx, rtx);
|
||||
extern int store_multiple_operation (rtx, enum machine_mode);
|
||||
extern int symbolic_operand (rtx, enum machine_mode);
|
||||
extern int impossible_plus_operand (rtx, enum machine_mode);
|
||||
|
||||
extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]);
|
||||
|
||||
extern bool mn10300_function_value_regno_p (const unsigned int);
|
||||
extern rtx legitimize_pic_address (rtx, rtx);
|
||||
extern int legitimate_pic_operand_p (rtx);
|
||||
extern bool mn10300_function_value_regno_p (const unsigned int);
|
||||
extern void mn10300_gen_multiple_store (int);
|
||||
extern int mn10300_get_live_callee_saved_regs (void);
|
||||
extern bool mn10300_hard_regno_mode_ok (unsigned int, Mmode);
|
||||
extern bool mn10300_legitimate_constant_p (rtx);
|
||||
extern bool mn10300_modes_tieable (Mmode, Mmode);
|
||||
extern Cstar mn10300_output_cmp (rtx, rtx);
|
||||
extern void mn10300_print_reg_list (FILE *, int);
|
||||
extern Rclas mn10300_secondary_reload_class (Rclas, Mmode, rtx);
|
||||
extern Mmode mn10300_select_cc_mode (rtx);
|
||||
extern bool mn10300_wide_const_load_uses_clr (rtx operands[2]);
|
||||
extern void print_operand (FILE *, rtx, int);
|
||||
extern void print_operand_address (FILE *, rtx);
|
||||
extern int store_multiple_operation (rtx, Mmode);
|
||||
extern int symbolic_operand (rtx, Mmode);
|
||||
#endif /* RTX_CODE */
|
||||
|
||||
#ifdef TREE_CODE
|
||||
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *, Mmode, tree, int);
|
||||
#endif /* TREE_CODE */
|
||||
|
||||
extern void expand_prologue (void);
|
||||
extern void expand_epilogue (void);
|
||||
extern int initial_offset (int, int);
|
||||
extern int can_use_return_insn (void);
|
||||
extern int mask_ok_for_mem_btst (int, int);
|
||||
extern int can_use_return_insn (void);
|
||||
extern void expand_prologue (void);
|
||||
extern void expand_epilogue (void);
|
||||
extern int initial_offset (int, int);
|
||||
extern int mask_ok_for_mem_btst (int, int);
|
||||
|
||||
#undef Mmode
|
||||
#undef Cstar
|
||||
#undef Rclas
|
||||
|
|
|
@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
#include "target-def.h"
|
||||
#include "df.h"
|
||||
|
||||
/* This is used by GOTaddr2picreg to uniquely identify
|
||||
UNSPEC_INT_LABELs. */
|
||||
|
@ -190,12 +191,6 @@ mn10300_option_override (void)
|
|||
{
|
||||
if (TARGET_AM33)
|
||||
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
|
||||
|
@ -220,7 +215,7 @@ print_operand (FILE *file, rtx x, int code)
|
|||
{
|
||||
case 'b':
|
||||
case 'B':
|
||||
if (cc_status.mdep.fpCC)
|
||||
if (GET_MODE (XEXP (x, 0)) == CC_FLOATmode)
|
||||
{
|
||||
switch (code == 'b' ? 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 = get_frame_size () + crtl->outgoing_args_size;
|
||||
size += (crtl->outgoing_args_size ? 4 : 0);
|
||||
|
||||
|
||||
if (TARGET_AM33_2 && fp_regs_to_save ())
|
||||
{
|
||||
int num_regs_to_save = fp_regs_to_save (), i;
|
||||
|
@ -1236,59 +1231,6 @@ expand_epilogue (void)
|
|||
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().
|
||||
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
|
||||
|
@ -1413,11 +1355,6 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
|
|||
|| XEXP (in, 1) == stack_pointer_rtx))))
|
||||
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
|
||||
&& rclass == FP_REGS)
|
||||
{
|
||||
|
@ -1425,7 +1362,7 @@ mn10300_secondary_reload_class (enum reg_class rclass, enum machine_mode mode,
|
|||
constant address. */
|
||||
if (GET_CODE (in) == MEM
|
||||
&& 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
|
||||
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
|
||||
&& reg_equiv_mem [REGNO (inner)]
|
||||
&& 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. */
|
||||
|
@ -1696,9 +1633,10 @@ mn10300_function_value_regno_p (const unsigned int regno)
|
|||
return (regno == FIRST_DATA_REGNUM || regno == FIRST_ADDRESS_REGNUM);
|
||||
}
|
||||
|
||||
/* Output a tst insn. */
|
||||
/* Output a compare insn. */
|
||||
|
||||
const char *
|
||||
output_tst (rtx operand, rtx insn)
|
||||
mn10300_output_cmp (rtx operand, rtx insn)
|
||||
{
|
||||
rtx temp;
|
||||
int past_call = 0;
|
||||
|
@ -1786,19 +1724,6 @@ output_tst (rtx operand, rtx insn)
|
|||
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
|
||||
the source operand might end up in memory. */
|
||||
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
|
||||
(mn10300, hppa) it is used to rewrite certain problematical addresses. */
|
||||
rtx
|
||||
static rtx
|
||||
mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED)
|
||||
{
|
||||
|
@ -1941,7 +1866,7 @@ legitimate_pic_operand_p (rtx x)
|
|||
{
|
||||
if (fmt[i] == 'E')
|
||||
{
|
||||
register int j;
|
||||
int j;
|
||||
|
||||
for (j = XVECLEN (x, i) - 1; j >= 0; 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
|
||||
function record_unscaled_index_insn_codes. */
|
||||
|
||||
bool
|
||||
static bool
|
||||
mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
|
||||
{
|
||||
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
|
||||
&& GET_CODE (XEXP (index, 0)) != PLUS
|
||||
&& (! flag_pic
|
||||
|| legitimate_pic_operand_p (index)))
|
||||
|| (legitimate_pic_operand_p (index)
|
||||
&& GET_MODE_SIZE (mode) == 4)))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -2017,6 +1943,55 @@ mn10300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
|
|||
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
|
||||
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
|
||||
serious code efficiency lossage. */
|
||||
|
||||
unsigned int mn10300_case_values_threshold (void)
|
||||
static unsigned int
|
||||
mn10300_case_values_threshold (void)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
@ -2310,3 +2286,48 @@ mn10300_can_output_mi_thunk (const_tree thunk_fndecl ATTRIBUTE_UNUSED,
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -117,28 +117,32 @@ extern enum processor_type mn10300_processor;
|
|||
All registers that the compiler knows about must be given numbers,
|
||||
even those that are not normally considered general registers. */
|
||||
|
||||
#define FIRST_PSEUDO_REGISTER 51
|
||||
#define FIRST_PSEUDO_REGISTER 52
|
||||
|
||||
/* Specify machine-specific register numbers. */
|
||||
#define FIRST_DATA_REGNUM 0
|
||||
#define LAST_DATA_REGNUM 3
|
||||
#define FIRST_ADDRESS_REGNUM 4
|
||||
#define LAST_ADDRESS_REGNUM 8
|
||||
/* Specify machine-specific register numbers. The commented out entries
|
||||
are defined in mn10300.md. */
|
||||
#define FIRST_DATA_REGNUM 0
|
||||
#define LAST_DATA_REGNUM 3
|
||||
#define FIRST_ADDRESS_REGNUM 4
|
||||
/* #define PIC_REG 6 */
|
||||
#define LAST_ADDRESS_REGNUM 8
|
||||
/* #define SP_REG 9 */
|
||||
#define FIRST_EXTENDED_REGNUM 10
|
||||
#define LAST_EXTENDED_REGNUM 17
|
||||
#define FIRST_FP_REGNUM 18
|
||||
#define LAST_FP_REGNUM 49
|
||||
#define MDR_REGNUM 50
|
||||
#define FIRST_ARGUMENT_REGNUM 0
|
||||
#define LAST_EXTENDED_REGNUM 17
|
||||
#define FIRST_FP_REGNUM 18
|
||||
#define LAST_FP_REGNUM 49
|
||||
#define MDR_REGNUM 50
|
||||
/* #define CC_REG 51 */
|
||||
#define FIRST_ARGUMENT_REGNUM 0
|
||||
|
||||
/* Specify the registers used for certain standard purposes.
|
||||
The values of these macros are register numbers. */
|
||||
|
||||
/* 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. */
|
||||
#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
|
||||
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
|
||||
|
||||
/* 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
|
||||
and are not available for the register allocator. */
|
||||
|
||||
#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, 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 \
|
||||
, 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.
|
||||
|
@ -167,8 +171,8 @@ extern enum processor_type mn10300_processor;
|
|||
|
||||
#define CALL_USED_REGISTERS \
|
||||
{ 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 \
|
||||
, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 \
|
||||
, 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, 1 \
|
||||
}
|
||||
|
||||
/* Note: The definition of CALL_REALLY_USED_REGISTERS is not
|
||||
|
@ -181,7 +185,7 @@ extern enum processor_type mn10300_processor;
|
|||
#define REG_ALLOC_ORDER \
|
||||
{ 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 \
|
||||
, 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 \
|
||||
|
@ -197,8 +201,7 @@ extern enum processor_type mn10300_processor;
|
|||
if (!TARGET_AM33_2) \
|
||||
{ \
|
||||
for (i = FIRST_FP_REGNUM; \
|
||||
i <= LAST_FP_REGNUM; \
|
||||
i++) \
|
||||
i <= LAST_FP_REGNUM; i++) \
|
||||
fixed_regs[i] = call_used_regs[i] = 1; \
|
||||
} \
|
||||
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
|
||||
MODE. */
|
||||
|
||||
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
|
||||
((REGNO_REG_CLASS (REGNO) == DATA_REGS \
|
||||
|| (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)
|
||||
mn10300_hard_regno_mode_ok ((REGNO), (MODE))
|
||||
|
||||
/* Value is 1 if it is a good idea to tie two pseudo registers
|
||||
when one has mode MODE1 and one has mode 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. */
|
||||
#define MODES_TIEABLE_P(MODE1, MODE2) \
|
||||
(TARGET_AM33 \
|
||||
|| MODE1 == MODE2 \
|
||||
|| (GET_MODE_SIZE (MODE1) <= 4 && GET_MODE_SIZE (MODE2) <= 4))
|
||||
mn10300_modes_tieable ((MODE1), (MODE2))
|
||||
|
||||
/* 4 data, and effectively 3 address registers is small as far as I'm
|
||||
concerned. */
|
||||
|
@ -263,7 +259,7 @@ enum reg_class {
|
|||
DATA_OR_ADDRESS_REGS, SP_OR_ADDRESS_REGS,
|
||||
EXTENDED_REGS, DATA_OR_EXTENDED_REGS, 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
|
||||
};
|
||||
|
||||
|
@ -271,35 +267,36 @@ enum reg_class {
|
|||
|
||||
/* Give names of register classes as strings for dump file. */
|
||||
|
||||
#define REG_CLASS_NAMES \
|
||||
{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
|
||||
"SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
|
||||
"EXTENDED_REGS", \
|
||||
"DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
|
||||
"SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
|
||||
"FP_REGS", "FP_ACC_REGS", \
|
||||
#define REG_CLASS_NAMES \
|
||||
{ "NO_REGS", "DATA_REGS", "ADDRESS_REGS", \
|
||||
"SP_REGS", "DATA_OR_ADDRESS_REGS", "SP_OR_ADDRESS_REGS", \
|
||||
"EXTENDED_REGS", \
|
||||
"DATA_OR_EXTENDED_REGS", "ADDRESS_OR_EXTENDED_REGS", \
|
||||
"SP_OR_EXTENDED_REGS", "SP_OR_ADDRESS_OR_EXTENDED_REGS", \
|
||||
"FP_REGS", "FP_ACC_REGS", "CC_REGS", \
|
||||
"GENERAL_REGS", "ALL_REGS", "LIM_REGS" }
|
||||
|
||||
/* Define which registers fit in which classes.
|
||||
This is an initializer for a vector of HARD_REG_SET
|
||||
of length N_REG_CLASSES. */
|
||||
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ { 0, 0 }, /* No regs */ \
|
||||
{ 0x0000f, 0 }, /* DATA_REGS */ \
|
||||
{ 0x001f0, 0 }, /* ADDRESS_REGS */ \
|
||||
{ 0x00200, 0 }, /* SP_REGS */ \
|
||||
{ 0x001ff, 0 }, /* DATA_OR_ADDRESS_REGS */\
|
||||
{ 0x003f0, 0 }, /* SP_OR_ADDRESS_REGS */\
|
||||
{ 0x3fc00, 0 }, /* EXTENDED_REGS */ \
|
||||
{ 0x3fc0f, 0 }, /* DATA_OR_EXTENDED_REGS */ \
|
||||
{ 0x3fdf0, 0 }, /* ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{ 0x3fe00, 0 }, /* SP_OR_EXTENDED_REGS */ \
|
||||
{ 0x3fff0, 0 }, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{ 0xfffc0000, 0x3ffff }, /* FP_REGS */ \
|
||||
{ 0x03fc0000, 0 }, /* FP_ACC_REGS */ \
|
||||
{ 0x3fdff, 0 }, /* GENERAL_REGS */ \
|
||||
{ 0xffffffff, 0x7ffff } /* ALL_REGS */ \
|
||||
#define REG_CLASS_CONTENTS \
|
||||
{ { 0, 0 }, /* No regs */ \
|
||||
{ 0x0000000f, 0 }, /* DATA_REGS */ \
|
||||
{ 0x000001f0, 0 }, /* ADDRESS_REGS */ \
|
||||
{ 0x00000200, 0 }, /* SP_REGS */ \
|
||||
{ 0x000001ff, 0 }, /* DATA_OR_ADDRESS_REGS */ \
|
||||
{ 0x000003f0, 0 }, /* SP_OR_ADDRESS_REGS */ \
|
||||
{ 0x0003fc00, 0 }, /* EXTENDED_REGS */ \
|
||||
{ 0x0003fc0f, 0 }, /* DATA_OR_EXTENDED_REGS */ \
|
||||
{ 0x0003fdf0, 0 }, /* ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{ 0x0003fe00, 0 }, /* SP_OR_EXTENDED_REGS */ \
|
||||
{ 0x0003fff0, 0 }, /* SP_OR_ADDRESS_OR_EXTENDED_REGS */ \
|
||||
{ 0xfffc0000, 0x3ffff },/* FP_REGS */ \
|
||||
{ 0x03fc0000, 0 }, /* FP_ACC_REGS */ \
|
||||
{ 0x00000000, 0x80000 },/* CC_REGS */ \
|
||||
{ 0x0003fdff, 0 }, /* GENERAL_REGS */ \
|
||||
{ 0xffffffff, 0xfffff } /* ALL_REGS */ \
|
||||
}
|
||||
|
||||
/* The following macro defines cover classes for Integrated Register
|
||||
|
@ -326,6 +323,7 @@ enum reg_class {
|
|||
(REGNO) == STACK_POINTER_REGNUM ? SP_REGS : \
|
||||
(REGNO) <= LAST_EXTENDED_REGNUM ? EXTENDED_REGS : \
|
||||
(REGNO) <= LAST_FP_REGNUM ? FP_REGS : \
|
||||
(REGNO) == CC_REG ? CC_REGS : \
|
||||
NO_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 OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
|
||||
#define ACCUMULATE_OUTGOING_ARGS 1
|
||||
|
||||
#if 1
|
||||
/* So we can allocate space for return pointers once for the function
|
||||
instead of around every call. */
|
||||
#define STACK_POINTER_OFFSET 4
|
||||
#endif
|
||||
|
||||
/* 1 if N is a possible register number for function argument passing.
|
||||
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.
|
||||
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
|
||||
#define LEGITIMATE_CONSTANT_P(X) 1
|
||||
#define LEGITIMATE_CONSTANT_P(X) mn10300_legitimate_constant_p (X)
|
||||
|
||||
/* Zero if this needs fixing up to become PIC. */
|
||||
|
||||
|
@ -675,20 +673,9 @@ struct cum_arg {int nbytes; };
|
|||
goto FAIL; \
|
||||
while (0)
|
||||
|
||||
/* Tell final.c how to eliminate redundant test instructions. */
|
||||
|
||||
/* 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 SELECT_CC_MODE(OP, X, Y) mn10300_select_cc_mode (X)
|
||||
#define REVERSIBLE_CC_MODE(MODE) 0
|
||||
|
||||
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
|
||||
((CLASS1 == CLASS2 && (CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS)) ? 2 :\
|
||||
((CLASS1 == ADDRESS_REGS || CLASS1 == DATA_REGS) && \
|
||||
|
@ -762,24 +749,26 @@ struct cum_arg {int nbytes; };
|
|||
/* How to refer to registers in assembler output.
|
||||
This sequence is indexed by compiler's hard-register-number (see above). */
|
||||
|
||||
#define REGISTER_NAMES \
|
||||
{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" \
|
||||
, "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" \
|
||||
, "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15" \
|
||||
, "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23" \
|
||||
, "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31", "mdr" \
|
||||
#define REGISTER_NAMES \
|
||||
{ "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "ap", "sp", \
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" \
|
||||
, "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" \
|
||||
, "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15" \
|
||||
, "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23" \
|
||||
, "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31" \
|
||||
, "mdr", "EPSW" \
|
||||
}
|
||||
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
{ {"r8", 4}, {"r9", 5}, {"r10", 6}, {"r11", 7}, \
|
||||
{"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3}, \
|
||||
{"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13}, \
|
||||
{"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17} \
|
||||
, {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24} \
|
||||
, {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32} \
|
||||
, {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40} \
|
||||
, {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48} \
|
||||
#define ADDITIONAL_REGISTER_NAMES \
|
||||
{ {"r8", 4}, {"r9", 5}, {"r10", 6}, {"r11", 7}, \
|
||||
{"r12", 0}, {"r13", 1}, {"r14", 2}, {"r15", 3}, \
|
||||
{"e0", 10}, {"e1", 11}, {"e2", 12}, {"e3", 13}, \
|
||||
{"e4", 14}, {"e5", 15}, {"e6", 16}, {"e7", 17} \
|
||||
, {"fd0", 18}, {"fd2", 20}, {"fd4", 22}, {"fd6", 24} \
|
||||
, {"fd8", 26}, {"fd10", 28}, {"fd12", 30}, {"fd14", 32} \
|
||||
, {"fd16", 34}, {"fd18", 36}, {"fd20", 38}, {"fd22", 40} \
|
||||
, {"fd24", 42}, {"fd26", 44}, {"fd28", 46}, {"fd30", 48} \
|
||||
, {"cc", CC_REG} \
|
||||
}
|
||||
|
||||
/* 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 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. */
|
||||
|
||||
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
|
||||
|
@ -883,12 +869,3 @@ struct cum_arg {int nbytes; };
|
|||
|
||||
#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
|
@ -47,3 +47,10 @@
|
|||
|
||||
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;
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue