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
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);
#ifdef RTX_CODE
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
/* 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
#define FIRST_PSEUDO_REGISTER 52
/* 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)
;; GCC machine description for Matsushita MN10300
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
;; 2007, 2008 Free Software Foundation, Inc.
;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
;; 2005, 2006, 2007, 2008, 2009, 2010
;; Free Software Foundation, Inc.
;; Contributed by Jeff Law (law@cygnus.com).
;; This file is part of GCC.
......@@ -24,21 +25,10 @@
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
;; Condition code settings.
;; none - insn does not affect cc
;; none_0hit - insn does not affect cc but it does modify operand 0
;; This attribute is used to keep track of when operand 0 changes.
;; See the description of NOTICE_UPDATE_CC for more info.
;; set_znv - insn sets z,n,v to usable values; c is unusable.
;; set_zn - insn sets z,n to usable values; v,c are unusable.
;; compare - compare instruction
;; clobber - value of cc is unknown
(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber"
(const_string "clobber"))
(define_constants [
(PIC_REG 6)
(SP_REG 9)
(PIC_REG 6)
(SP_REG 9)
(CC_REG 51)
(UNSPEC_INT_LABEL 0)
(UNSPEC_PIC 1)
......@@ -58,20 +48,20 @@
;; movqi
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
(match_operand:QI 1 "general_operand" ""))]
[(set (match_operand:QI 0 "general_operand")
(match_operand:QI 1 "general_operand"))]
""
"
{
/* One of the ops has to be in a register */
/* One of the ops has to be in a register. */
if (!register_operand (operand0, QImode)
&& !register_operand (operand1, QImode))
operands[1] = copy_to_mode_reg (QImode, operand1);
}")
(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
(match_operand:QI 1 "general_operand" "0,I,d*xai,m,d*xa,d*xa*f,*f"))]
(define_insn "*am33_movqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "=d*x*a*f,d*x*a,d*x*a,m,*f,d*x*a")
(match_operand:QI 1 "general_operand" "0,d*xai,m,d*xa,d*xa*f,*f"))]
"TARGET_AM33
&& (register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode))"
......@@ -82,8 +72,6 @@
case 0:
return \"nop\";
case 1:
return \"clr %0\";
case 2:
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
rtx xoperands[2];
......@@ -103,19 +91,19 @@
return \"movu %1,%0\";
}
return \"mov %1,%0\";
case 2:
case 3:
case 4:
return \"movbu %1,%0\";
case 4:
case 5:
case 6:
return \"fmov %1,%0\";
default:
gcc_unreachable ();
}
}"
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
)
(define_insn ""
(define_insn "*mn10300_movqi"
[(set (match_operand:QI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
(match_operand:QI 1 "general_operand" "0,I,i,i,da,m,d"))]
"register_operand (operands[0], QImode)
......@@ -127,7 +115,6 @@
case 0:
return \"nop\";
case 1:
return \"clr %0\";
case 2:
case 3:
case 4:
......@@ -148,25 +135,25 @@
gcc_unreachable ();
}
}"
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
)
;; movhi
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
[(set (match_operand:HI 0 "general_operand")
(match_operand:HI 1 "general_operand"))]
""
"
{
/* One of the ops has to be in a register */
/* One of the ops has to be in a register. */
if (!register_operand (operand1, HImode)
&& !register_operand (operand0, HImode))
operands[1] = copy_to_mode_reg (HImode, operand1);
}")
(define_insn ""
[(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x,d*x*a,d*x*a,m,*f,d*x*a")
(match_operand:HI 1 "general_operand" "0,I,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
(define_insn "*am33_movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=d*x*a*f,d*x*a,d*x*a,m,*f,d*x*a")
(match_operand:HI 1 "general_operand" "0,d*x*ai,m,d*x*a,d*x*a*f,*f"))]
"TARGET_AM33
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
......@@ -177,8 +164,6 @@
case 0:
return \"nop\";
case 1:
return \"clr %0\";
case 2:
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
rtx xoperands[2];
......@@ -198,19 +183,19 @@
return \"movu %1,%0\";
}
return \"mov %1,%0\";
case 2:
case 3:
case 4:
return \"movhu %1,%0\";
case 4:
case 5:
case 6:
return \"fmov %1,%0\";
default:
gcc_unreachable ();
}
}"
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
)
(define_insn ""
(define_insn "*mn10300_movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=d*a,d,d,!*a,d*a,d,m")
(match_operand:HI 1 "general_operand" "0,I,i,i,da,m,d"))]
"register_operand (operands[0], HImode)
......@@ -222,7 +207,6 @@
case 0:
return \"nop\";
case 1:
return \"clr %0\";
case 2:
case 3:
case 4:
......@@ -242,7 +226,7 @@
gcc_unreachable ();
}
}"
[(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
)
;; movsi and helpers
......@@ -250,12 +234,14 @@
;; stack pointer and the other is a memory reference of some kind. Reload
;; does not handle them correctly without this expander.
(define_expand "reload_insi"
[(set (match_operand:SI 0 "register_operand" "=a")
(match_operand:SI 1 "impossible_plus_operand" ""))
[(set (match_operand:SI 0 "register_operand" "=a")
(match_operand:SI 1 "impossible_plus_operand" ""))
(clobber (match_operand:SI 2 "register_operand" "=&r"))]
""
"
{
gcc_assert (REGNO (operands[0]) != REGNO (operands[2]));
if (XEXP (operands[1], 0) == stack_pointer_rtx)
{
if (GET_CODE (XEXP (operands[1], 1)) == SUBREG
......@@ -293,12 +279,12 @@
"movm (sp),[a2]")
(define_expand "movsi"
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
[(set (match_operand:SI 0 "general_operand")
(match_operand:SI 1 "general_operand"))]
""
"
{
/* One of the ops has to be in a register */
/* One of the ops has to be in a register. */
if (!register_operand (operand1, SImode)
&& !register_operand (operand0, SImode))
operands[1] = copy_to_mode_reg (SImode, operand1);
......@@ -334,7 +320,7 @@
}
}")
(define_insn ""
(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand"
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,axR,!*y,*f,*f,dxaQ")
(match_operand:SI 1 "general_operand"
......@@ -349,7 +335,6 @@
case 1:
return \"nop\";
case 2:
return \"clr %0\";
case 3:
case 4:
case 5:
......@@ -389,23 +374,23 @@
gcc_unreachable ();
}
}"
[(set_attr "cc" "none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none,none_0hit,none_0hit")])
)
(define_expand "movsf"
[(set (match_operand:SF 0 "general_operand" "")
(match_operand:SF 1 "general_operand" ""))]
[(set (match_operand:SF 0 "general_operand")
(match_operand:SF 1 "general_operand"))]
""
"
{
/* One of the ops has to be in a register */
/* One of the ops has to be in a register. */
if (!register_operand (operand1, SFmode)
&& !register_operand (operand0, SFmode))
operands[1] = copy_to_mode_reg (SFmode, operand1);
}")
(define_insn ""
(define_insn "*movsf_internal"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f,dx,ax,dx,a,f,dxaQ,daxm,dax")
(match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
(match_operand:SF 1 "general_operand" "0,0,0,G,G,fdxaQF,f,dax,daxFm"))]
"register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode)"
"*
......@@ -416,12 +401,11 @@
case 1:
case 2:
return \"nop\";
case 3:
return \"clr %0\";
/* case 4: below */
/* Cases 3 & 4: below. */
case 5:
case 6:
return \"fmov %1, %0\";
case 3:
case 4:
case 7:
case 8:
......@@ -439,21 +423,21 @@
gcc_unreachable ();
}
}"
[(set_attr "cc" "none,none,none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")])
)
(define_expand "movdi"
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
[(set (match_operand:DI 0 "general_operand")
(match_operand:DI 1 "general_operand"))]
""
"
{
/* One of the ops has to be in a register */
/* One of the ops has to be in a register. */
if (!register_operand (operand1, DImode)
&& !register_operand (operand0, DImode))
operands[1] = copy_to_mode_reg (DImode, operand1);
}")
(define_insn ""
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand"
"=dx,ax,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax,*f,*f,*f,dxa,*f,Q")
(match_operand:DI 1 "general_operand"
......@@ -472,7 +456,7 @@
return \"nop\";
case 2:
return \"clr %L0\;clr %H0\";
return \"mov 0, %L0\;mov 0, %H0\";
case 3:
if (rtx_equal_p (operands[0], operands[1]))
......@@ -546,7 +530,7 @@
&& val[0] == 0)
{
if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
output_asm_insn (\"clr %L0\", operands);
output_asm_insn (\"mov 0, %L0\", operands);
else
output_asm_insn (\"mov %L1,%L0\", operands);
}
......@@ -565,7 +549,7 @@
&& val[1] == 0)
{
if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
output_asm_insn (\"clr %H0\", operands);
output_asm_insn (\"mov 0, %H0\", operands);
else
output_asm_insn (\"mov %H1,%H0\", operands);
}
......@@ -608,47 +592,30 @@
gcc_unreachable ();
}
}"
[(set (attr "cc")
(cond
[
(ior (lt (symbol_ref "which_alternative") (const_int 2))
(eq (symbol_ref "which_alternative") (const_int 12))
) (const_string "none")
(eq (symbol_ref "which_alternative") (const_int 2)
) (const_string "clobber")
(eq (symbol_ref "which_alternative") (const_int 3)
) (if_then_else
(ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
(const_int 0)) (const_string "clobber")
(const_string "none_0hit"))
(ior (eq (symbol_ref "which_alternative") (const_int 8))
(eq (symbol_ref "which_alternative") (const_int 9))
) (if_then_else
(ne (symbol_ref "mn10300_wide_const_load_uses_clr
(operands)")
(const_int 0)) (const_string "clobber")
(const_string "none_0hit"))
] (const_string "none_0hit")))])
)
(define_expand "movdf"
[(set (match_operand:DF 0 "general_operand" "")
(match_operand:DF 1 "general_operand" ""))]
[(set (match_operand:DF 0 "general_operand")
(match_operand:DF 1 "general_operand"))]
""
"
{
/* One of the ops has to be in a register */
/* One of the ops has to be in a register. */
if (!register_operand (operand1, DFmode)
&& !register_operand (operand0, DFmode))
operands[1] = copy_to_mode_reg (DFmode, operand1);
}")
(define_insn ""
(define_insn "*am33_2_movdf"
[(set (match_operand:DF 0 "nonimmediate_operand"
;; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
"=f,dx,ax,dx,f,f,dxa,f,Q,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
(match_operand:DF 1 "general_operand"
;; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
"0,0,0,G,f,dxaF,f,Q,f,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
"register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode)"
"TARGET_AM33_2
&& (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"
"*
{
long val[2];
......@@ -662,7 +629,7 @@
return \"nop\";
case 3:
return \"clr %L0\;clr %H0\";
return \"mov 0, %L0\;mov 0, %H0\";
case 4:
case 5:
......@@ -757,7 +724,7 @@
&& val[0] == 0)
{
if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
output_asm_insn (\"clr %L0\", operands);
output_asm_insn (\"mov 0, %L0\", operands);
else
output_asm_insn (\"mov %L1,%L0\", operands);
}
......@@ -776,7 +743,7 @@
&& val[1] == 0)
{
if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
output_asm_insn (\"clr %H0\", operands);
output_asm_insn (\"mov 0, %H0\", operands);
else
output_asm_insn (\"mov %H1,%H0\", operands);
}
......@@ -799,119 +766,167 @@
gcc_unreachable ();
}
}"
[(set (attr "cc")
(cond
[
(lt (symbol_ref "which_alternative") (const_int 3)
) (const_string "none")
(eq (symbol_ref "which_alternative") (const_int 3)
) (const_string "clobber")
(eq (symbol_ref "which_alternative") (const_int 9)
) (if_then_else
(ne (symbol_ref "rtx_equal_p (operands[0], operands[1])")
(const_int 0)) (const_string "clobber")
(const_string "none_0hit"))
(ior (eq (symbol_ref "which_alternative") (const_int 14))
(eq (symbol_ref "which_alternative") (const_int 15))
) (if_then_else
(ne (symbol_ref "mn10300_wide_const_load_uses_clr
(operands)")
(const_int 0)) (const_string "clobber")
(const_string "none_0hit"))
] (const_string "none_0hit")))])
)
(define_insn "*mn10300_movdf"
[(set (match_operand:DF 0 "nonimmediate_operand"
;; 0 1 2 3 4 5 6 7 8 9 10
"=dxa,dx,a,dxm,dxm,axm,axm,dx,dx,ax,ax")
(match_operand:DF 1 "general_operand"
;; 0 1 2 3 4 5 6 7 8 9 10
"0,G,G,dx,ax,dx,ax,dxFm,axFm,dxFm,axFm"))]
"register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode)"
"*
{
long val[2];
REAL_VALUE_TYPE rv;
;; ----------------------------------------------------------------------
;; TEST INSTRUCTIONS
;; ----------------------------------------------------------------------
switch (which_alternative)
{
case 0:
return \"nop\";
(define_insn "*tst_extqisi_am33"
[(set (cc0) (compare
(zero_extend:SI (match_operand:QI 0 "memory_operand" "dx,!a"))
(const_int 0)))]
"TARGET_AM33"
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
case 1:
return \"mov 0, %L0\;mov 0, %H0\";
(define_insn "*tst_extqisi"
[(set (cc0) (compare
(zero_extend:SI (match_operand:QI 0 "memory_operand" "dx"))
(const_int 0)))]
""
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
case 2:
if (rtx_equal_p (operands[0], operands[1]))
return \"sub %L1,%L0\;mov %L0,%H0\";
else
return \"mov %1,%L0\;mov %L0,%H0\";
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
if (GET_CODE (operands[1]) == CONST_INT)
{
rtx low, high;
split_double (operands[1], &low, &high);
val[0] = INTVAL (low);
val[1] = INTVAL (high);
}
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
if (GET_MODE (operands[1]) == DFmode)
{
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_DOUBLE (rv, val);
}
else if (GET_MODE (operands[1]) == VOIDmode
|| GET_MODE (operands[1]) == DImode)
{
val[0] = CONST_DOUBLE_LOW (operands[1]);
val[1] = CONST_DOUBLE_HIGH (operands[1]);
}
}
(define_insn "*tst_exthisi_am33"
[(set (cc0) (compare
(zero_extend:SI (match_operand:HI 0 "memory_operand" "dx,!a"))
(const_int 0)))]
"TARGET_AM33"
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
if (GET_CODE (operands[1]) == MEM
&& reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
{
rtx temp = operands[0];
(define_insn "*tst_exthisi"
[(set (cc0) (compare
(zero_extend:SI (match_operand:HI 0 "memory_operand" "dx"))
(const_int 0)))]
""
"* return output_tst (operands[0], insn);"
[(set_attr "cc" "set_znv")])
while (GET_CODE (temp) == SUBREG)
temp = SUBREG_REG (temp);
;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
;; its operands hold equal values, but the operands of a cmp
;; instruction must be distinct registers. In the case where we'd
;; like to compare a register to itself, we can achieve this effect
;; with a btst 0,d0 instead. (This will not alter the contents of d0
;; but will have the proper effect on cc0. Using d0 is arbitrary; any
;; data register would work.)
gcc_assert (GET_CODE (temp) == REG);
;; Even though the first alternative would be preferable if it can
;; possibly match, reload must not be given the opportunity to attempt
;; to use it. It assumes that such matches can only occur when one of
;; the operands is used for input and the other for output. Since
;; this is not the case, it abort()s. Indeed, such a reload cannot be
;; possibly satisfied, so just mark the alternative with a `!', so
;; that it is not considered by reload.
if (reg_overlap_mentioned_p (gen_rtx_REG (SImode, REGNO (temp)),
XEXP (operands[1], 0)))
return \"mov %H1,%H0\;mov %L1,%L0\";
else
return \"mov %L1,%L0\;mov %H1,%H0\";
(define_insn "*cmpsi"
[(set (cc0)
(compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax,dax")
(match_operand:SI 1 "nonmemory_operand" "*0,I,daxi")))]
""
"*
{
if (which_alternative == 0)
return \"btst 0,d0\";
if (which_alternative == 1)
return output_tst (operands[0], insn);
return \"cmp %1,%0\";
}"
[(set_attr "cc" "compare,set_znv,compare")])
}
else if (GET_CODE (operands[1]) == MEM
&& CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
&& REGNO_REG_CLASS (REGNO (operands[0])) == ADDRESS_REGS)
{
rtx xoperands[2];
(define_insn "*cmpsf"
[(set (cc0)
(compare (match_operand:SF 0 "register_operand" "f,f")
(match_operand:SF 1 "nonmemory_operand" "f,F")))]
"TARGET_AM33_2"
"fcmp %1,%0"
[(set_attr "cc" "compare,compare")])
xoperands[0] = operands[0];
xoperands[1] = XEXP (operands[1], 0);
output_asm_insn (\"mov %1,%L0\;mov (4,%L0),%H0\;mov (%L0),%L0\",
xoperands);
return \"\";
}
else
{
if ((GET_CODE (operands[1]) == CONST_INT
|| GET_CODE (operands[1]) == CONST_DOUBLE)
&& val[0] == 0)
{
if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
output_asm_insn (\"mov 0, %L0\", operands);
else
output_asm_insn (\"mov %L1,%L0\", operands);
}
else if ((GET_CODE (operands[1]) == CONST_INT
|| GET_CODE (operands[1]) == CONST_DOUBLE)
&& (REGNO_REG_CLASS (true_regnum (operands[0]))
== EXTENDED_REGS)
&& (((val[0] & 0x80) && ! (val[0] & 0xffffff00))
|| ((val[0] & 0x800000) && ! (val[0] & 0xff000000))))
output_asm_insn (\"movu %L1,%L0\", operands);
else
output_asm_insn (\"mov %L1,%L0\", operands);
if ((GET_CODE (operands[1]) == CONST_INT
|| GET_CODE (operands[1]) == CONST_DOUBLE)
&& val[1] == 0)
{
if (REGNO_REG_CLASS (REGNO (operands[0])) == DATA_REGS)
output_asm_insn (\"mov 0, %H0\", operands);
else
output_asm_insn (\"mov %H1,%H0\", operands);
}
else if ((GET_CODE (operands[1]) == CONST_INT
|| GET_CODE (operands[1]) == CONST_DOUBLE)
&& val[0] == val[1])
output_asm_insn (\"mov %L0,%H0\", operands);
else if ((GET_CODE (operands[1]) == CONST_INT
|| GET_CODE (operands[1]) == CONST_DOUBLE)
&& (REGNO_REG_CLASS (true_regnum (operands[0]))
== EXTENDED_REGS)
&& (((val[1] & 0x80) && ! (val[1] & 0xffffff00))
|| ((val[1] & 0x800000) && ! (val[1] & 0xff000000))))
output_asm_insn (\"movu %H1,%H0\", operands);
else
output_asm_insn (\"mov %H1,%H0\", operands);
return \"\";
}
default:
gcc_unreachable ();
}
}"
)
;; ----------------------------------------------------------------------
;; ADD INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_expand "addsi3"
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(plus:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
(define_insn "*am33_addsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,a,x,a,dax,!*y,!dax")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,dax")
(match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))]
(match_operand:SI 2 "nonmemory_operand" "J,J,L,L,daxi,i,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -985,12 +1000,14 @@
gcc_unreachable ();
}
}"
[(set_attr "cc" "set_zn,none_0hit,set_zn,none_0hit,set_zn,none_0hit,set_zn")])
)
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
(define_insn "*mn10300_addsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,a,a,dax,!*y,!dax")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,dax")
(match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))]
(match_operand:SI 2 "nonmemory_operand" "J,J,L,daxi,i,dax")))
(clobber (reg:CC CC_REG))
]
""
"*
{
......@@ -1027,20 +1044,23 @@
gcc_unreachable ();
}
}"
[(set_attr "cc" "set_zn,none_0hit,none_0hit,set_zn,none_0hit,set_zn")])
)
;; ----------------------------------------------------------------------
;; SUBTRACT INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_expand "subsi3"
[(set (match_operand:SI 0 "register_operand" "")
(minus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(minus:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_subsi3"
[(set (match_operand:SI 0 "register_operand" "=dax,!dax")
(minus:SI (match_operand:SI 1 "register_operand" "0,dax")
(match_operand:SI 2 "nonmemory_operand" "daxi,dax")))]
......@@ -1068,19 +1088,21 @@
return \"sub %2,%1,%0\";
}
}"
[(set_attr "cc" "set_zn")])
)
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dax")
(define_insn "*mn10300_subsi3"
[(set (match_operand:SI 0 "register_operand" "=dax")
(minus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "nonmemory_operand" "daxi")))]
(match_operand:SI 2 "nonmemory_operand" "daxi")))
(clobber (reg:CC CC_REG))
]
""
"sub %2,%0"
[(set_attr "cc" "set_zn")])
)
(define_expand "negsi2"
[(set (match_operand:SI 0 "register_operand" "")
(neg:SI (match_operand:SI 1 "register_operand" "")))]
[(set (match_operand:SI 0 "register_operand")
(neg:SI (match_operand:SI 1 "register_operand")))]
""
"
{
......@@ -1099,30 +1121,39 @@
(define_insn "mulsidi3"
[(set (match_operand:DI 0 "register_operand" "=dax")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "dax"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
(sign_extend:DI (match_operand:SI 2 "register_operand" "dax"))))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"mul %1,%2,%H0,%L0"
[(set_attr "cc" "set_zn")])
)
(define_insn "umulsidi3"
[(set (match_operand:DI 0 "register_operand" "=dax")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "dax"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))]
(zero_extend:DI (match_operand:SI 2 "register_operand" "dax"))))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"mulu %1,%2,%H0,%L0"
[(set_attr "cc" "set_zn")])
)
(define_expand "mulsi3"
[(set (match_operand:SI 0 "register_operand" "")
(mult:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(mult:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "register_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(define_insn "*am33_mulsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(mult:SI (match_operand:SI 1 "register_operand" "%0,0")
(match_operand:SI 2 "nonmemory_operand" "dx,daxi")))]
(match_operand:SI 2 "nonmemory_operand" "dx,daxi")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -1131,12 +1162,14 @@
else
return \"mul %2,%0\";
}"
[(set_attr "cc" "set_zn")])
)
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx")
(define_insn "*mn10300_mulsi3"
[(set (match_operand:SI 0 "register_operand" "=dx")
(mult:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "register_operand" "dx")))]
(match_operand:SI 2 "register_operand" "dx")))
(clobber (reg:CC CC_REG))
]
""
"*
{
......@@ -1145,14 +1178,34 @@
else
return \"mul %2,%0\";
}"
[(set_attr "cc" "set_zn")])
(define_insn "udivmodsi4"
)
(define_expand "udivmodsi4"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
(udiv:SI (match_operand:SI 1 "general_operand")
(match_operand:SI 2 "general_operand")))
(set (match_operand:SI 3 "nonimmediate_operand")
(umod:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC CC_REG))
])
]
""
"{
if (!register_operand (operands[1], SImode))
operands[1] = copy_to_mode_reg (SImode, operands[1]);
if (!register_operand (operands[2], SImode))
operands[2] = copy_to_mode_reg (SImode, operands[2]);
}"
)
(define_insn "*udivmodsi4_insn"
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
(udiv:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "dx")))
(udiv:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "register_operand" "dx")))
(set (match_operand:SI 3 "nonimmediate_operand" "=&d")
(umod:SI (match_dup 1) (match_dup 2)))]
(umod:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC CC_REG))
]
""
"*
{
......@@ -1163,14 +1216,16 @@
else
return \"divu %2,%0\;mov mdr,%3\";
}"
[(set_attr "cc" "set_zn")])
)
(define_insn "divmodsi4"
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
(div:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "dx")))
(set (match_operand:SI 3 "nonimmediate_operand" "=d")
(mod:SI (match_dup 1) (match_dup 2)))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx")
(div:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "dx")))
(set (match_operand:SI 3 "nonimmediate_operand" "=d")
(mod:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC CC_REG))
]
""
"*
{
......@@ -1179,7 +1234,7 @@
else
return \"ext %0\;div %2,%0\;mov mdr,%3\";
}"
[(set_attr "cc" "set_zn")])
)
;; ----------------------------------------------------------------------
......@@ -1187,16 +1242,21 @@
;; ----------------------------------------------------------------------
(define_expand "andsi3"
[(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(and:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
(define_insn "*am33_andsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,dx,!dax")
(and:SI (match_operand:SI 1 "register_operand" "%0,0,dax")
(match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))]
(match_operand:SI 2 "nonmemory_operand" "N,dxi,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -1236,27 +1296,14 @@
return \"and %1,%0\";
return \"and %2,%0\";
}"
[(set (attr "cc")
(cond
[
(eq (symbol_ref "which_alternative") (const_int 0)
) (const_string "none_0hit")
(ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
&& (INTVAL (operands[2]) == 0x7fffffff
|| INTVAL (operands[2]) == 0x3fffffff
|| INTVAL (operands[2]) == 0x1fffffff
|| INTVAL (operands[2]) == 0x0fffffff
|| INTVAL (operands[2]) == 0xfffffffe
|| INTVAL (operands[2]) == 0xfffffffc
|| INTVAL (operands[2]) == 0xfffffff8
|| INTVAL (operands[2]) == 0xfffffff0)")
(const_int 0)) (const_string "set_zn")
] (const_string "set_znv")))])
)
(define_insn ""
(define_insn "*mn10300_andsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,dx")
(and:SI (match_operand:SI 1 "register_operand" "%0,0")
(match_operand:SI 2 "nonmemory_operand" "N,dxi")))]
(match_operand:SI 2 "nonmemory_operand" "N,dxi")))
(clobber (reg:CC CC_REG))
]
""
"*
{
......@@ -1282,43 +1329,28 @@
return \"lsr 4,%0\;asl2 %0\;asl2 %0\";
return \"and %2,%0\";
}"
[(set (attr "cc")
(cond
[
(eq (symbol_ref "which_alternative") (const_int 0)
) (const_string "none_0hit")
;; Shifts don't set the V flag, but bitwise operations clear
;; it (which correctly reflects the absence of overflow in a
;; compare-with-zero that might follow). As for the
;; 0xfffffffe case, the add may overflow, so we can't use the
;; V flag.
(ne (symbol_ref "GET_CODE (operands[2]) == CONST_INT
&& (INTVAL (operands[2]) == 0x7fffffff
|| INTVAL (operands[2]) == 0x3fffffff
|| INTVAL (operands[2]) == 0x1fffffff
|| INTVAL (operands[2]) == 0x0fffffff
|| INTVAL (operands[2]) == 0xfffffffe
|| INTVAL (operands[2]) == 0xfffffffc
|| INTVAL (operands[2]) == 0xfffffff8
|| INTVAL (operands[2]) == 0xfffffff0)")
(const_int 0)) (const_string "set_zn")
] (const_string "set_znv")))])
)
;; ----------------------------------------------------------------------
;; OR INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_expand "iorsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ior:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(ior:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_iorsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(ior:SI (match_operand:SI 1 "register_operand" "%0,dax")
(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -1338,31 +1370,38 @@
return \"or %1,%0\";
return \"or %2,%0\";
}"
[(set_attr "cc" "set_znv")])
)
(define_insn ""
(define_insn "*mn10300_iorsi3"
[(set (match_operand:SI 0 "register_operand" "=dx")
(ior:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "nonmemory_operand" "dxi")))]
(match_operand:SI 2 "nonmemory_operand" "dxi")))
(clobber (reg:CC CC_REG))
]
""
"or %2,%0"
[(set_attr "cc" "set_znv")])
)
;; ----------------------------------------------------------------------
;; XOR INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_expand "xorsi3"
[(set (match_operand:SI 0 "register_operand" "")
(xor:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(xor:SI (match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_xorsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(xor:SI (match_operand:SI 1 "register_operand" "%0,dax")
(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))]
(match_operand:SI 2 "nonmemory_operand" "dxi,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -1382,39 +1421,48 @@
return \"xor %1,%0\";
return \"xor %2,%0\";
}"
[(set_attr "cc" "set_znv")])
)
(define_insn ""
(define_insn "*mn10300_xorsi3"
[(set (match_operand:SI 0 "register_operand" "=dx")
(xor:SI (match_operand:SI 1 "register_operand" "%0")
(match_operand:SI 2 "nonmemory_operand" "dxi")))]
(match_operand:SI 2 "nonmemory_operand" "dxi")))
(clobber (reg:CC CC_REG))
]
""
"xor %2,%0"
[(set_attr "cc" "set_znv")])
)
;; ----------------------------------------------------------------------
;; NOT INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_expand "one_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "")
(not:SI (match_operand:SI 1 "register_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(not:SI (match_operand:SI 1 "register_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(not:SI (match_operand:SI 1 "register_operand" "0,0")))]
(define_insn "*am33_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(not:SI (match_operand:SI 1 "register_operand" "0,0")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"not %0"
[(set_attr "cc" "set_znv")])
)
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=dx")
(not:SI (match_operand:SI 1 "register_operand" "0")))]
(define_insn "*mn10300_cmplsi2"
[(set (match_operand:SI 0 "register_operand" "=dx")
(not:SI (match_operand:SI 1 "register_operand" "0")))
(clobber (reg:CC CC_REG))
]
""
"not %0"
[(set_attr "cc" "set_znv")])
)
;; -----------------------------------------------------------------
;; BIT FIELDS
......@@ -1426,95 +1474,112 @@
;; They are no smaller/faster than loading the value into a register
;; and storing the register, but they don't need a scratch register
;; which may allow for better code generation.
(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))]
""
(define_insn "*byte_clear"
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int 0))
(clobber (reg:CC CC_REG))
]
"GET_CODE (operands[0]) != MEM || (! MEM_VOLATILE_P (operands[0]) && GET_CODE (XEXP (operands[0], 0)) != PLUS)"
"@
bclr 255,%A0
clr %0"
[(set_attr "cc" "clobber")])
)
(define_insn ""
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))]
""
(define_insn "*byte_set"
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,d") (const_int -1))
(clobber (reg:CC CC_REG))
]
"GET_CODE (operands[0]) != MEM || (! MEM_VOLATILE_P (operands[0]) && GET_CODE (XEXP (operands[0], 0)) != PLUS)"
"@
bset 255,%A0
mov -1,%0"
[(set_attr "cc" "clobber,none_0hit")])
)
(define_insn ""
(define_insn "*bit_clear1"
[(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
(subreg:QI
(and:SI (subreg:SI (match_dup 0) 0)
(match_operand:SI 1 "const_int_operand" "i,i")) 0))]
(match_operand:SI 1 "const_int_operand" "i,i")) 0))
(clobber (reg:CC CC_REG))
]
""
"@
bclr %N1,%A0
and %1,%0"
[(set_attr "cc" "clobber,set_znv")])
)
(define_insn ""
(define_insn "*bit_clear2"
[(set (match_operand:QI 0 "memory_operand" "=R,T")
(and:QI
(match_dup 0)
(not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))]
(not:QI (match_operand:QI 1 "nonmemory_operand" "i,d"))))
(clobber (reg:CC CC_REG))
]
""
"@
bclr %U1,%A0
bclr %1,%0"
[(set_attr "cc" "clobber,clobber")])
)
(define_insn ""
(define_insn "*bit_set"
[(set (match_operand:QI 0 "nonimmediate_operand" "+R,d")
(subreg:QI
(ior:SI (subreg:SI (match_dup 0) 0)
(match_operand:SI 1 "const_int_operand" "i,i")) 0))]
(match_operand:SI 1 "const_int_operand" "i,i")) 0))
(clobber (reg:CC CC_REG))
]
""
"@
bset %U1,%A0
or %1,%0"
[(set_attr "cc" "clobber,set_znv")])
)
(define_expand "iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:QI 0 "nonimmediate_operand")
(ior:QI (match_operand:QI 1 "nonimmediate_operand")
(match_operand:QI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,r")
(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
;; This constraint should really be nonmemory_operand,
;; but making it general_operand, along with the
;; condition that not both input operands are MEMs, it
;; here helps combine do a better job.
(match_operand:QI 2 "general_operand" "i,d,ir")))]
(match_operand:QI 2 "general_operand" "i,d,ir")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33 &&
(GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
bset %U2,%A0
bset %2,%0
or %2,%0"
[(set_attr "cc" "clobber,clobber,set_znv")])
)
(define_insn ""
(define_insn "*mn10300_iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "=R,T,d")
(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
;; This constraint should really be nonmemory_operand,
;; but making it general_operand, along with the
;; condition that not both input operands are MEMs, it
;; here helps combine do a better job.
(match_operand:QI 2 "general_operand" "i,d,id")))]
(match_operand:QI 2 "general_operand" "i,d,id")))
(clobber (reg:CC CC_REG))
]
"GET_CODE (operands[2]) != MEM || GET_CODE (operands[1]) != MEM"
"@
bset %U2,%A0
bset %2,%0
or %2,%0"
[(set_attr "cc" "clobber,clobber,set_znv")])
)
(define_insn ""
[(set (cc0)
(define_insn "*test_int_bitfield"
[(set (reg:CC CC_REG)
(compare (zero_extract:SI (match_operand:SI 0 "register_operand" "dx")
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" ""))
......@@ -1539,10 +1604,10 @@
output_asm_insn (\"btst %1,%0\", xoperands);
return \"\";
}"
[(set_attr "cc" "clobber")])
)
(define_insn ""
[(set (cc0)
(define_insn "*test_byte_bitfield"
[(set (reg:CC CC_REG)
(compare (zero_extract:SI (match_operand:QI 0 "general_operand" "R,dx")
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" ""))
......@@ -1585,18 +1650,20 @@
output_asm_insn (\"btst %U1,%A0\", xoperands);
return \"\";
}"
[(set_attr "cc" "clobber")])
)
(define_insn ""
[(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "dx")
(match_operand:SI 1 "const_int_operand" ""))
(const_int 0)))]
(define_insn "*bit_test"
[(set (reg:CC CC_REG)
(compare (and:SI (match_operand:SI 0 "register_operand" "dx")
(match_operand:SI 1 "const_int_operand" ""))
(const_int 0)))
]
""
"btst %1,%0"
[(set_attr "cc" "clobber")])
)
(define_insn ""
[(set (cc0)
(define_insn "*subreg_bit_test"
[(set (reg:CC CC_REG)
(compare (and:SI
(subreg:SI (match_operand:QI 0 "general_operand" "R,dx") 0)
(match_operand:SI 1 "const_8bit_operand" ""))
......@@ -1605,83 +1672,144 @@
"@
btst %U1,%A0
btst %1,%0"
[(set_attr "cc" "clobber")])
)
;; ----------------------------------------------------------------------
;; JUMP INSTRUCTIONS
;; COMPARE AND BRANCH INSTRUCTIONS
;; ----------------------------------------------------------------------
;; We expand the comparison into a single insn so that it will not be split
;; up by reload.
(define_expand "cbranchsi4"
[(set (cc0)
(compare (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))
(set (pc)
(if_then_else
(match_operator 0 "ordered_comparison_operator" [(cc0)
(const_int 0)])
(label_ref (match_operand 3 "" ""))
[(set (pc)
(if_then_else
(match_operator 0 "ordered_comparison_operator"
[(match_operand:SI 1 "register_operand")
(match_operand:SI 2 "nonmemory_operand")])
(label_ref (match_operand 3 ""))
(pc)))]
""
"")
""
)
(define_expand "cbranchsf4"
[(set (cc0)
(compare (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonmemory_operand" "")))
(set (pc)
(if_then_else
(match_operator 0 "ordered_comparison_operator" [(cc0)
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_AM33_2"
"")
(define_insn_and_split "*cbranchsi4_post_reload"
[(set (pc)
(if_then_else (match_operator 3 "ordered_comparison_operator"
[(match_operand:SI 0 "register_operand" "dax")
(match_operand:SI 1 "nonmemory_operand" "daxi")])
(label_ref (match_operand 2 "" ""))
(pc)))
]
""
"#"
"reload_completed"
[(const_int 0)]
"
/* We construct the split by hand as otherwise the JUMP_LABEL
attribute is not set correctly on the jump insn. */
emit_insn (gen_cmpsi (operands[0], operands[1]));
emit_jump_insn (gen_integer_conditional_branch (gen_rtx_fmt_ee (GET_CODE (operands[3]),
CCmode,
gen_rtx_REG (CCmode, CC_REG),
const0_rtx),
operands[2]));
"
)
;; Ordinarily, the cmp instruction will set the Z bit of cc0 to 1 if
;; its operands hold equal values, but the operands of a cmp
;; instruction must be distinct registers. In the case where we'd
;; like to compare a register to itself, we can achieve this effect
;; with a btst 0,d0 instead. (This will not alter the contents of d0
;; but will have the proper effect on cc0. Using d0 is arbitrary; any
;; data register would work.)
;; Even though the first alternative would be preferable if it can
;; possibly match, reload must not be given the opportunity to attempt
;; to use it. It assumes that such matches can only occur when one of
;; the operands is used for input and the other for output. Since
;; this is not the case, it abort()s. Indeed, such a reload cannot be
;; possibly satisfied, so just mark the alternative with a `!', so
;; that it is not considered by reload.
;; Conditional jump instructions
(define_insn "cmpsi"
[(set (reg:CC CC_REG)
(compare (match_operand:SI 0 "register_operand" "!*d*a*x,dax,dax")
(match_operand:SI 1 "nonmemory_operand" "*0,I,daxi")))]
""
{
if (which_alternative == 0)
return \"btst 0,d0\";
if (which_alternative == 1)
return mn10300_output_cmp (operands[0], insn);
return \"cmp %1,%0\";
}
)
(define_insn ""
(define_insn "integer_conditional_branch"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(if_then_else (match_operator 0 "comparison_operator" [(reg:CC CC_REG) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
""
"*
{
if (cc_status.mdep.fpCC)
return \"fb%b1 %0\";
if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
&& (GET_CODE (operands[1]) == GT
|| GET_CODE (operands[1]) == GE
|| GET_CODE (operands[1]) == LE
|| GET_CODE (operands[1]) == LT))
return 0;
return \"b%b1 %0\";
}"
[(set_attr "cc" "none")])
"b%b0 %1"
)
(define_insn ""
(define_expand "cbranchsf4"
[(set (pc)
(if_then_else (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
(if_then_else
(match_operator 0 "ordered_comparison_operator"
[(match_operand:SF 1 "register_operand")
(match_operand:SF 2 "nonmemory_operand")])
(label_ref (match_operand 3 ""))
(pc)))]
"TARGET_AM33_2"
""
"*
{
if (cc_status.mdep.fpCC)
return \"fb%B1 %0\";
if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0
&& (GET_CODE (operands[1]) == GT
|| GET_CODE (operands[1]) == GE
|| GET_CODE (operands[1]) == LE
|| GET_CODE (operands[1]) == LT))
return 0;
return \"b%B1 %0\";
}"
[(set_attr "cc" "none")])
)
(define_insn_and_split "*cbranchsf4_post_reload"
[(set (pc)
(if_then_else (match_operator 3 "ordered_comparison_operator"
[(match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "nonmemory_operand" "fF")])
(label_ref (match_operand 2 "" ""))
(pc)))
]
"TARGET_AM33_2"
"#"
"&& reload_completed"
[(const_int 0)]
"
/* We construct the split by hand as otherwise the JUMP_LABEL
attribute is not set correctly on the jump insn. */
emit_insn (gen_am33_cmpsf (operands[0], operands[1]));
emit_jump_insn (gen_float_conditional_branch (gen_rtx_fmt_ee (GET_CODE (operands[3]),
CC_FLOATmode,
gen_rtx_REG (CC_FLOATmode, CC_REG),
const0_rtx),
operands[2]));
"
)
(define_insn "am33_cmpsf"
[(set (reg:CC_FLOAT CC_REG)
(compare:CC_FLOAT (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "nonmemory_operand" "fF")))]
"TARGET_AM33_2"
"fcmp %1, %0"
)
(define_insn "float_conditional_branch"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator" [(reg:CC_FLOAT CC_REG) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
"TARGET_AM33_2"
"fb%b0 %1"
)
;; Unconditional and other jump instructions.
......@@ -1690,13 +1818,13 @@
(label_ref (match_operand 0 "" "")))]
""
"jmp %l0"
[(set_attr "cc" "none")])
)
(define_insn "indirect_jump"
[(set (pc) (match_operand:SI 0 "register_operand" "a"))]
""
"jmp (%0)"
[(set_attr "cc" "none")])
)
(define_expand "builtin_setjmp_receiver"
[(match_operand 0 "" "")]
......@@ -1710,10 +1838,10 @@
}")
(define_expand "casesi"
[(match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "immediate_operand" "")
(match_operand:SI 2 "immediate_operand" "")
(match_operand 3 "" "") (match_operand 4 "" "")]
[(match_operand:SI 0 "register_operand")
(match_operand:SI 1 "immediate_operand")
(match_operand:SI 2 "immediate_operand")
(match_operand 3 "" "") (match_operand 4 "")]
""
"
{
......@@ -1723,15 +1851,15 @@
rtx test;
emit_move_insn (table, gen_rtx_LABEL_REF (VOIDmode, operands[3]));
emit_move_insn (index, plus_constant (operands[0], - INTVAL (operands[1])));
emit_insn (gen_addsi3 (index, operands[0], GEN_INT (- INTVAL (operands[1]))));
test = gen_rtx_fmt_ee (GTU, VOIDmode, index, operands[2]);
emit_jump_insn (gen_cbranchsi4 (test, index, operands[2], operands[4]));
emit_move_insn (index, gen_rtx_ASHIFT (SImode, index, const2_rtx));
emit_insn (gen_ashlsi3 (index, index, const2_rtx));
emit_move_insn (addr, gen_rtx_MEM (SImode,
gen_rtx_PLUS (SImode, table, index)));
if (flag_pic)
emit_move_insn (addr, gen_rtx_PLUS (SImode, addr, table));
emit_insn (gen_addsi3 (addr, addr, table));
emit_jump_insn (gen_tablejump (addr, operands[3]));
DONE;
......@@ -1742,13 +1870,13 @@
(use (label_ref (match_operand 1 "" "")))]
""
"jmp (%0)"
[(set_attr "cc" "none")])
)
;; Call subroutine with no return value.
(define_expand "call"
[(call (match_operand:QI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
[(call (match_operand:QI 0 "general_operand")
(match_operand:SI 1 "general_operand"))]
""
"
{
......@@ -1785,15 +1913,15 @@
else
return \"call %C0,[],0\";
}"
[(set_attr "cc" "clobber")])
)
;; Call subroutine, returning value in operand 0
;; (which must be a hard register).
(define_expand "call_value"
[(set (match_operand 0 "" "")
(call (match_operand:QI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
[(set (match_operand 0 "")
(call (match_operand:QI 1 "general_operand")
(match_operand:SI 2 "general_operand")))]
""
"
{
......@@ -1833,13 +1961,13 @@
else
return \"call %C1,[],0\";
}"
[(set_attr "cc" "clobber")])
)
(define_expand "untyped_call"
[(parallel [(call (match_operand 0 "" "")
[(parallel [(call (match_operand 0 "")
(const_int 0))
(match_operand 1 "" "")
(match_operand 2 "" "")])]
(match_operand 1 "")
(match_operand 2 "")])]
""
"
{
......@@ -1859,16 +1987,16 @@
[(const_int 0)]
""
"nop"
[(set_attr "cc" "none")])
)
;; ----------------------------------------------------------------------
;; EXTEND INSTRUCTIONS
;; ----------------------------------------------------------------------
(define_expand "zero_extendqisi2"
[(set (match_operand:SI 0 "general_operand" "")
[(set (match_operand:SI 0 "general_operand")
(zero_extend:SI
(match_operand:QI 1 "general_operand" "")))]
(match_operand:QI 1 "general_operand")))]
""
"")
......@@ -1884,7 +2012,7 @@
extbu %0
mov %1,%0\;extbu %0
movbu %1,%0"
[(set_attr "cc" "none_0hit")])
)
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
......@@ -1895,12 +2023,12 @@
extbu %0
mov %1,%0\;extbu %0
movbu %1,%0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "general_operand" "")
[(set (match_operand:SI 0 "general_operand")
(zero_extend:SI
(match_operand:HI 1 "general_operand" "")))]
(match_operand:HI 1 "general_operand")))]
""
"")
......@@ -1916,7 +2044,7 @@
exthu %0
mov %1,%0\;exthu %0
movhu %1,%0"
[(set_attr "cc" "none_0hit")])
)
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx,dx")
......@@ -1927,14 +2055,14 @@
exthu %0
mov %1,%0\;exthu %0
movhu %1,%0"
[(set_attr "cc" "none_0hit")])
)
;;- sign extension instructions
(define_expand "extendqisi2"
[(set (match_operand:SI 0 "general_operand" "")
[(set (match_operand:SI 0 "general_operand")
(sign_extend:SI
(match_operand:QI 1 "general_operand" "")))]
(match_operand:QI 1 "general_operand")))]
""
"")
......@@ -1948,7 +2076,7 @@
mov %1,%0\;extb %0
extb %0
mov %1,%0\;extb %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
......@@ -1958,12 +2086,12 @@
"@
extb %0
mov %1,%0\;extb %0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "general_operand" "")
[(set (match_operand:SI 0 "general_operand")
(sign_extend:SI
(match_operand:HI 1 "general_operand" "")))]
(match_operand:HI 1 "general_operand")))]
""
"")
......@@ -1977,7 +2105,7 @@
mov %1,%0\;exth %0
exth %0
mov %1,%0\;exth %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn ""
[(set (match_operand:SI 0 "nonimmediate_operand" "=dx,dx")
......@@ -1987,25 +2115,30 @@
"@
exth %0
mov %1,%0\;exth %0"
[(set_attr "cc" "none_0hit")])
)
;; ----------------------------------------------------------------------
;; SHIFTS
;; ----------------------------------------------------------------------
(define_expand "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashift:SI
(match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(ashift:SI
(match_operand:SI 1 "register_operand")
(match_operand:QI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=dax,dx,!dax")
(ashift:SI
(match_operand:SI 1 "register_operand" "0,0,dax")
(match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))]
(match_operand:QI 2 "nonmemory_operand" "J,dxi,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -2032,13 +2165,15 @@
return \"mov %1,%0\;asl %S2,%0\";
return \"asl %2,%1,%0\";
}"
[(set_attr "cc" "set_zn")])
)
(define_insn ""
(define_insn "*mn10300_ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=dax,dx,dx,dx,dx")
(ashift:SI
(match_operand:SI 1 "register_operand" "0,0,0,0,0")
(match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))]
(match_operand:QI 2 "nonmemory_operand" "J,K,M,L,dxi")))
(clobber (reg:CC CC_REG))
]
""
"@
add %0,%0
......@@ -2046,21 +2181,26 @@
asl2 %0\;add %0,%0
asl2 %0\;asl2 %0
asl %S2,%0"
[(set_attr "cc" "set_zn")])
)
(define_expand "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI
(match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(lshiftrt:SI
(match_operand:SI 1 "register_operand")
(match_operand:QI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(lshiftrt:SI
(match_operand:SI 1 "register_operand" "0,dax")
(match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
(match_operand:QI 2 "nonmemory_operand" "dxi,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -2073,30 +2213,37 @@
return \"mov %1,%0\;lsr %S2,%0\";
return \"lsr %2,%1,%0\";
}"
[(set_attr "cc" "set_zn")])
)
(define_insn ""
(define_insn "*mn10300_lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=dx")
(lshiftrt:SI
(match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "dxi")))]
(match_operand:QI 2 "nonmemory_operand" "dxi")))
(clobber (reg:CC CC_REG))
]
""
"lsr %S2,%0"
[(set_attr "cc" "set_zn")])
)
(define_expand "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI
(match_operand:SI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand")
(ashiftrt:SI
(match_operand:SI 1 "register_operand")
(match_operand:QI 2 "nonmemory_operand")))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_insn ""
(define_insn "*am33_ashrisi3"
[(set (match_operand:SI 0 "register_operand" "=dx,!dax")
(ashiftrt:SI
(match_operand:SI 1 "register_operand" "0,dax")
(match_operand:QI 2 "nonmemory_operand" "dxi,dax")))]
(match_operand:QI 2 "nonmemory_operand" "dxi,dax")))
(clobber (reg:CC CC_REG))
]
"TARGET_AM33"
"*
{
......@@ -2109,16 +2256,18 @@
return \"mov %1,%0\;asr %S2,%0\";
return \"asr %2,%1,%0\";
}"
[(set_attr "cc" "set_zn")])
)
(define_insn ""
(define_insn "*mn10300_ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=dx")
(ashiftrt:SI
(match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "nonmemory_operand" "dxi")))]
(match_operand:QI 2 "nonmemory_operand" "dxi")))
(clobber (reg:CC CC_REG))
]
""
"asr %S2,%0"
[(set_attr "cc" "set_zn")])
)
;; ----------------------------------------------------------------------
;; FP INSTRUCTIONS
......@@ -2132,8 +2281,8 @@
;;
(define_expand "absdf2"
[(set (match_operand:DF 0 "register_operand" "")
(abs:DF (match_operand:DF 1 "register_operand" "")))]
[(set (match_operand:DF 0 "register_operand")
(abs:DF (match_operand:DF 1 "register_operand")))]
""
"
{
......@@ -2161,8 +2310,8 @@
}")
(define_expand "abssf2"
[(set (match_operand:SF 0 "register_operand" "")
(abs:SF (match_operand:SF 1 "register_operand" "")))]
[(set (match_operand:SF 0 "register_operand")
(abs:SF (match_operand:SF 1 "register_operand")))]
""
"
{
......@@ -2191,17 +2340,17 @@
(define_insn "abssf2_am33_2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
[(set (match_operand:SF 0 "register_operand" "=f,f")
(abs:SF (match_operand:SF 1 "register_operand" "0,?f")))]
"TARGET_AM33_2"
"@
fabs %0
fabs %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "negdf2"
[(set (match_operand:DF 0 "register_operand" "")
(neg:DF (match_operand:DF 1 "register_operand" "")))]
[(set (match_operand:DF 0 "register_operand")
(neg:DF (match_operand:DF 1 "register_operand")))]
""
"
{
......@@ -2230,8 +2379,8 @@
}")
(define_expand "negsf2"
[(set (match_operand:SF 0 "register_operand" "")
(neg:SF (match_operand:SF 1 "register_operand" "")))]
[(set (match_operand:SF 0 "register_operand")
(neg:SF (match_operand:SF 1 "register_operand")))]
""
"
{
......@@ -2260,17 +2409,17 @@
}")
(define_insn "negsf2_am33_2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
[(set (match_operand:SF 0 "register_operand" "=f,f")
(neg:SF (match_operand:SF 1 "register_operand" "0,?f")))]
"TARGET_AM33_2"
"@
fneg %0
fneg %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "")
(sqrt:SF (match_operand:SF 1 "register_operand" "")))]
[(set (match_operand:SF 0 "register_operand")
(sqrt:SF (match_operand:SF 1 "register_operand")))]
"TARGET_AM33_2 && flag_unsafe_math_optimizations"
"
{
......@@ -2282,91 +2431,138 @@
}")
(define_insn "rsqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
(sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))]
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 2 "const_1f_operand" "F,F")
(sqrt:SF (match_operand:SF 1 "register_operand" "0,?f"))))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"@
frsqrt %0
frsqrt %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "addsf3"
[(parallel [(set (match_operand:SF 0 "register_operand")
(plus:SF (match_operand:SF 1 "register_operand")
(match_operand:SF 2 "nonmemory_operand")))
(clobber (reg:CC_FLOAT CC_REG))])
]
"TARGET_AM33_2"
""
)
(define_insn "addsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(define_insn "*addsf3_internal"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "register_operand" "%0,f")
(match_operand:SF 2 "general_operand" "f,?fF")))]
(match_operand:SF 2 "general_operand" "f,?fF")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"@
fadd %2, %0
fadd %2, %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "subsf3"
[(parallel [(set (match_operand:SF 0 "register_operand")
(minus:SF (match_operand:SF 1 "register_operand")
(match_operand:SF 2 "nonmemory_operand")))
(clobber (reg:CC_FLOAT CC_REG))])
]
"TARGET_AM33_2"
""
)
(define_insn "subsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(define_insn "*subsf3_internal"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,f")
(match_operand:SF 2 "general_operand" "f,?fF")))]
(match_operand:SF 2 "general_operand" "f,?fF")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"@
fsub %2, %0
fsub %2, %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_expand "mulsf3"
[(parallel [(set (match_operand:SF 0 "register_operand")
(mult:SF (match_operand:SF 1 "register_operand")
(match_operand:SF 2 "nonmemory_operand")))
(clobber (reg:CC_FLOAT CC_REG))])
]
"TARGET_AM33_2"
""
)
(define_insn "mulsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(define_insn "*mulsf3_internal"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(mult:SF (match_operand:SF 1 "register_operand" "%0,f")
(match_operand:SF 2 "general_operand" "f,?fF")))]
(match_operand:SF 2 "general_operand" "f,?fF")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"@
fmul %2, %0
fmul %2, %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "register_operand" "0,f")
(match_operand:SF 2 "general_operand" "f,?fF")))]
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "register_operand" "0,f")
(match_operand:SF 2 "nonmemory_operand" "f,?fF")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"@
fdiv %2, %0
fdiv %2, %1, %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn "fmaddsf4"
[(set (match_operand:SF 0 "register_operand" "=A")
[(set (match_operand:SF 0 "register_operand" "=A")
(plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
(match_operand:SF 2 "register_operand" "f"))
(match_operand:SF 3 "register_operand" "f")))]
(match_operand:SF 3 "register_operand" "f")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"fmadd %1, %2, %3, %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn "fmsubsf4"
[(set (match_operand:SF 0 "register_operand" "=A")
[(set (match_operand:SF 0 "register_operand" "=A")
(minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
(match_operand:SF 2 "register_operand" "f"))
(match_operand:SF 3 "register_operand" "f")))]
(match_operand:SF 3 "register_operand" "f")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"fmsub %1, %2, %3, %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn "fnmaddsf4"
[(set (match_operand:SF 0 "register_operand" "=A")
(minus:SF (match_operand:SF 3 "register_operand" "f")
[(set (match_operand:SF 0 "register_operand" "=A")
(minus:SF (match_operand:SF 3 "register_operand" "f")
(mult:SF (match_operand:SF 1 "register_operand" "%f")
(match_operand:SF 2 "register_operand" "f"))))]
(match_operand:SF 2 "register_operand" "f"))))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"fnmadd %1, %2, %3, %0"
[(set_attr "cc" "none_0hit")])
)
(define_insn "fnmsubsf4"
[(set (match_operand:SF 0 "register_operand" "=A")
[(set (match_operand:SF 0 "register_operand" "=A")
(minus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%f")
(match_operand:SF 2 "register_operand" "f")))
(match_operand:SF 3 "register_operand" "f")))]
(match_operand:SF 3 "register_operand" "f")))
(clobber (reg:CC_FLOAT CC_REG))
]
"TARGET_AM33_2"
"fnmsub %1, %2, %3, %0"
[(set_attr "cc" "none_0hit")])
)
;; ----------------------------------------------------------------------
;; PROLOGUE/EPILOGUE
......@@ -2390,7 +2586,7 @@
(return)]
""
"rets"
[(set_attr "cc" "clobber")])
)
;; This insn restores the callee saved registers and does a return, it
;; can also deallocate stack space.
......@@ -2406,12 +2602,12 @@
fprintf (asm_out_file, \",%d\\n\", (int) INTVAL (operands[0]));
return \"\";
}"
[(set_attr "cc" "clobber")])
)
;; This instruction matches one generated by mn10300_gen_multiple_store()
(define_insn "store_movm"
[(match_parallel 0 "store_multiple_operation"
[(set (reg:SI 9) (plus:SI (reg:SI 9) (match_operand 1 "" "")))])]
[(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_operand 1 "" "")))])]
""
"*
{
......@@ -2421,7 +2617,7 @@
fprintf (asm_out_file, \",(sp)\\n\");
return \"\";
}"
[(set_attr "cc" "clobber")])
)
(define_insn "return"
[(return)]
......@@ -2437,73 +2633,29 @@
else
return \"rets\";
}"
[(set_attr "cc" "clobber")])
)
;; Try to combine consecutive updates of the stack pointer (or any
;; other register for that matter).
(define_peephole
[(set (match_operand:SI 0 "register_operand" "=dxay")
(plus:SI (match_dup 0)
(match_operand 1 "const_int_operand" "")))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand 2 "const_int_operand" "")))]
[(parallel [(set (match_operand:SI 0 "register_operand" "=dxay")
(plus:SI (match_dup 0)
(match_operand 1 "const_int_operand" "")))
(clobber (reg:CC CC_REG))
])
(parallel [(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand 2 "const_int_operand" "")))
(clobber (reg:CC CC_REG))
])
]
""
"*
{
operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]));
return \"add %1,%0\";
}"
[(set_attr "cc" "clobber")])
;;
;; We had patterns to check eq/ne, but the they don't work because
;; 0x80000000 + 0x80000000 = 0x0 with a carry out.
;;
;; The Z flag and C flag would be set, and we have no way to
;; check for the Z flag set and C flag clear.
;;
;; This will work on the mn10200 because we can check the ZX flag
;; if the comparison is in HImode.
(define_peephole
[(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
(const_int 0)))
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(match_operand 1 "" "")
(pc)))]
"dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
"add %0,%0\;bcc %1"
[(set_attr "cc" "clobber")])
(define_peephole
[(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
(const_int 0)))
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(match_operand 1 "" "")
(pc)))]
"dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
"add %0,%0\;bcs %1"
[(set_attr "cc" "clobber")])
(define_peephole
[(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
(const_int 0)))
(set (pc) (if_then_else (ge (cc0) (const_int 0))
(pc)
(match_operand 1 "" "")))]
"dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
"add %0,%0\;bcs %1"
[(set_attr "cc" "clobber")])
(define_peephole
[(set (cc0) (compare (match_operand:SI 0 "register_operand" "dx")
(const_int 0)))
(set (pc) (if_then_else (lt (cc0) (const_int 0))
(pc)
(match_operand 1 "" "")))]
"dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
"add %0,%0\;bcc %1"
[(set_attr "cc" "clobber")])
)
(define_expand "int_label"
[(unspec [(match_operand:SI 0 "" "")] UNSPEC_INT_LABEL)]
......@@ -2531,35 +2683,34 @@
[(set (reg:SI PIC_REG) (pc))
(use (match_operand 0 "" ""))])]
"TARGET_AM33"
"%0:\;mov pc,a2")
"%0:\;mov pc,a2"
)
(define_insn_and_split "mn10300_loadPC"
[(parallel
[(set (reg:SI PIC_REG) (pc))
(use (match_operand 0 "" ""))])]
""
"! TARGET_AM33"
"#"
"reload_completed"
"&& reload_completed"
[(match_operand 0 "" "")]
"
{
rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
int need_stack_space = (get_frame_size () == 0
&& crtl->outgoing_args_size == 0);
{
rtx sp_reg = gen_rtx_REG (SImode, SP_REG);
int need_stack_space = (get_frame_size () == 0
&& crtl->outgoing_args_size == 0);
if (need_stack_space)
emit_move_insn (sp_reg, plus_constant (sp_reg, -4));
if (need_stack_space)
emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-4)));
emit_insn (gen_call_next_insn (operands[0]));
emit_insn (gen_call_next_insn (operands[0]));
if (need_stack_space)
emit_insn (gen_pop_pic_reg ());
else
emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
DONE;
}")
if (need_stack_space)
emit_insn (gen_pop_pic_reg ());
else
emit_move_insn (pic_offset_table_rtx, gen_rtx_MEM (SImode, sp_reg));
DONE;
}
)
(define_insn "call_next_insn"
[(parallel
......@@ -2569,16 +2720,44 @@
"calls %0\;%0:")
(define_expand "add_GOT_to_pic_reg"
[(set (reg:SI PIC_REG)
(plus:SI
(reg:SI PIC_REG)
(const:SI
(unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_GOTSYM_OFF))))]
"")
[(parallel [(set (reg:SI PIC_REG)
(plus:SI
(reg:SI PIC_REG)
(const:SI
(unspec:SI [(minus:SI
(match_dup 1)
(const (minus:SI
(const (match_operand:SI 0 "" ""))
(pc))))
] UNSPEC_PIC))))
(clobber (reg:CC CC_REG))
])
]
""
"operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"
)
(define_expand "add_GOT_to_any_reg"
[(parallel [(set (match_operand:SI 0 "" "")
(plus:SI
(match_operand:SI 1 "" "")
(const
(unspec [(minus:SI
(match_dup 3)
(const (minus:SI
(const (match_operand:SI 2 "" ""))
(pc))))
] UNSPEC_PIC))))
(clobber (reg:CC CC_REG))
])
]
""
"operands[3] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);"
)
(define_expand "symGOT2reg"
[(match_operand:SI 0 "" "")
(match_operand:SI 1 "" "")]
[(match_operand:SI 0 "")
(match_operand:SI 1 "")]
""
"
{
......@@ -2592,15 +2771,15 @@
}")
(define_expand "symGOT2reg_i"
[(set (match_operand:SI 0 "" "")
[(set (match_operand:SI 0 "")
(mem:SI (plus:SI (reg:SI PIC_REG)
(const (unspec [(match_operand:SI 1 "" "")]
(const (unspec [(match_operand:SI 1 "")]
UNSPEC_GOT)))))]
""
"")
(define_expand "symGOTOFF2reg"
[(match_operand:SI 0 "" "") (match_operand:SI 1 "" "")]
[(match_operand:SI 0 "") (match_operand:SI 1 "")]
""
"
{
......@@ -2612,16 +2791,21 @@
}")
(define_expand "symGOTOFF2reg_i"
[(set (match_operand:SI 0 "" "")
(const (unspec [(match_operand:SI 1 "" "")] UNSPEC_GOTOFF)))
(set (match_dup 0) (plus:SI (match_dup 0) (reg:SI PIC_REG)))]
[(set (match_operand:SI 0 "")
(const (unspec [(match_operand:SI 1 "")] UNSPEC_GOTOFF)))
(parallel [(set (match_dup 0)
(plus:SI (match_dup 0)
(reg:SI PIC_REG)))
(clobber (reg:CC CC_REG))
])
]
""
"")
(define_expand "sym2PIC"
[(unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC)]
[(unspec [(match_operand:SI 0 "")] UNSPEC_PIC)]
"" "")
(define_expand "sym2PLT"
[(unspec [(match_operand:SI 0 "" "")] UNSPEC_PLT)]
[(unspec [(match_operand:SI 0 "")] UNSPEC_PLT)]
"" "")
......@@ -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