Commit 4af476d7 by Nick Clifton Committed by Nick Clifton

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
parent 6203e21a
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/>. */
#ifdef RTX_CODE
#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 bool mn10300_function_value_regno_p (const unsigned int);
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 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 bool mn10300_function_value_regno_p (const unsigned int);
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 int can_use_return_insn (void);
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);
#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)))
......@@ -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. */
/* 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 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,7 +150,7 @@ 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. */
......@@ -154,7 +158,7 @@ extern enum processor_type mn10300_processor;
#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, 1, 1 \
}
/* 1 for registers not available across function calls.
......@@ -168,7 +172,7 @@ 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 \
, 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
};
......@@ -277,7 +273,7 @@ enum reg_class {
"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_REGS" }
/* Define which registers fit in which classes.
......@@ -286,20 +282,21 @@ enum reg_class {
#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 */ \
{ 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 */ \
{ 0x3fdff, 0 }, /* GENERAL_REGS */ \
{ 0xffffffff, 0x7ffff } /* ALL_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,19 +673,8 @@ 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 :\
......@@ -768,7 +755,8 @@ struct cum_arg {int nbytes; };
, "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" \
, "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31" \
, "mdr", "EPSW" \
}
#define ADDITIONAL_REGISTER_NAMES \
......@@ -780,6 +768,7 @@ struct cum_arg {int nbytes; };
, {"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)
......@@ -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;
})
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment