From: Nick Clifton Date: Thu, 14 Oct 2010 09:12:50 +0000 (+0000) Subject: mn10300.h (CONSTANT_ALIGNMENT): Define. X-Git-Tag: upstream/12.2.0~89374 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4af476d7f2d3571c981b629995d3b3f1f8ffd3ab;p=platform%2Fupstream%2Fgcc.git mn10300.h (CONSTANT_ALIGNMENT): Define. * config/mn10300/mn10300.h (CONSTANT_ALIGNMENT): Define. (DATA_ALIGNMENT, LOCAL_ALIGNMENT): Define. (FIRST_PSEUDO_REGISTER): Increase by one. (FIXED_REGISTERS, CALL_USED_REGISTERS): Update with CC_REG. (HARD_REGNO_MODE_OK): Call mn10300_hard_regno_mode_ok. (MODES_TIEABLE): Call mn10300_modes_tieable. (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS): Add CC_REGS. (LEGITIMATE_CONSTANT_P): Call mn10300_legitimate_constant_p. (CC_OVERFLOW_UNUSABLE, CC_NO_CARRY, NOTICE_UPDATE_CC) (SELECT_CC_MODE, REVERSIBLE_CC_MODE): Delete. (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Add CC register. (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Delete. (mn10300_cc_status_mdep): Delete. (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Delete. * config/mn10300/mn10300 (mn10300_option_override): Stop disabling the combine-stack-adjust pass. (print_operand): Use the mode of the comparison operation to select the comparison suffix. (notice_update_cc): Delete. (mn10300_secondary_reload_class): Remove test for stack pointer based arithmetic. (output_tst): Rename to mn10300_output_cmp. (impossible_plus_operand): Move into predicates.md. (mn10300_legitimize_address): Make static. (mn10300_legitimate_address_p): Make static. Only allow SI sized constant pic operands. (mn10300_legitimate_constant_p): New function. (mn10300_case_values_threshold): Make static. (mn10300_hard_regno_mode_ok): New function. (mn10300_modes_tieable): New function. (mn10300_select_cc_mode): New function. * config/mn10300/predicates.md (impossible_plus_operand): Define. * config/mn10300/mn10300-protos.h: Tidy. (mn10300_legitimate_constant_p, mn10300_modes_tieable) (mn10300_hard_regno_mode_ok, mn10300_select_cc_mode): Prototype. * config/mn10300/mn10300.md (cc attribute): Delete. Replace with clobbers or sets of CC_REG. (CC_REG): Define. (mov*): Remove use of CLR instruction. (cbranch_si4_): New pattern/split. (integer_conditional_branch): New pattern. (cbranch_sf4_): 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a8a4eb..470849b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,53 @@ +2010-10-14 Nick Clifton + + * 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_): New pattern/split. + (integer_conditional_branch): New pattern. + (cbranch_sf4_): 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 * sel-sched-ir.c (init_global_and_expr_for_insn): Set CANT_MOVE diff --git a/gcc/config/mn10300/mn10300-protos.h b/gcc/config/mn10300/mn10300-protos.h index 02a7942..1e0f18e 100644 --- a/gcc/config/mn10300/mn10300-protos.h +++ b/gcc/config/mn10300/mn10300-protos.h @@ -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 . */ -#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 diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 47e5293..5e420a5 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -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; +} + diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index 26990ad..82f3e04 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -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) diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md index a2b6296..199617a 100644 --- a/gcc/config/mn10300/mn10300.md +++ b/gcc/config/mn10300/mn10300.md @@ -1,6 +1,7 @@ ;; 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)] "" "") diff --git a/gcc/config/mn10300/predicates.md b/gcc/config/mn10300/predicates.md index 8166e72..0f76a49 100644 --- a/gcc/config/mn10300/predicates.md +++ b/gcc/config/mn10300/predicates.md @@ -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; +})