From: ciceron Date: Thu, 3 May 2001 19:56:46 +0000 (+0000) Subject: Report fixes from 3_0-branch made on 2001-03-04: X-Git-Tag: upstream/4.9.2~94609 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=55abcb7ba5fc6ee75fe9b1fed51403d2d22faed0;p=platform%2Fupstream%2Flinaro-gcc.git Report fixes from 3_0-branch made on 2001-03-04: * config/m68hc11/larith.asm (__mulqi3): Fix multiplication of two negative numbers. (___subdi3, ___adddi3): Use x instead of y as index register. (__init_bss_section, __map_data_section): Optimize for 68HC12. (__memset, __memcpy): Likewise. (regs): Put the soft registers in bss for 68HC12. (abort): Use trap to abort for 68hc12. (__mulhi3, __mulhi32): Use emul for 68hc12. (__mulsi3): Avoid to use the tmp soft register for 68hc12. * config/m68hc11/m68hc11.h (LIMIT_RELOAD_CLASS): Don't define. * config/m68hc11/m68hc11-protos.h (limit_reload_class): Remove. * config/m68hc11/m68hc11.c (limit_reload_class): Remove. (m68hc11_override_options): Remove setting of flag_no_nonansi_builtin. Set 68HC12 min offset to -65536. (print_operand): Put parenthesis arround the operand if it refers to a symbol having the same name as a register. (m68hc11_z_replacement): When z register is replaced by its equivalent soft register, force the insn to be re-recognized. (m68hc11_check_z_replacement): Fix the test when destination is the index register and z dies in the insn. (m68hc11_reorg): Remove the REG_DEAD notes beforce recomputing them. * config/m68hc11/m68hc11.c (m68hc11_override_options): Initialize costs according to processor variant. (m68hc11_shift_cost): New function to compute shift costs. (m68hc11_rtx_costs): Define costs according to processor variant. (m6811_cost): Costs for 68HC11. (m6812_cost): Costs for 68HC12. (COSTS_N_INSNS): Remove. * config/m68hc11/m68hc11.h (RTX_COSTS): New. (DEFAULT_RTX_COSTS): Remove. (CONST_COSTS): Define costs according to OUTER_CODE. (processor_costs): New struct to define costs. (m68hc11_cost): Pointer to current costs. * config/m68hc11/m68hc11.md (*addhi3_68hc12): Fix generation and use m68hc11_notice_keep_cc when using leax/leay. (addhi3 split): Reject split if the insn is handled by leax/leay above. * config/m68hc11/m68hc11.c (m68hc11_split_move): For 68HC12 the push must be handled in a special way if the source operand uses sp as index register. (m68hc11_notice_keep_cc): New function. (m68hc11_gen_movhi): Use it when an insn changes a register but not the flags. (m68hc11_gen_movqi): Fix move for 68HC12. * config/m68hc11/m68hc11-protos.h (m68hc11_notice_keep_cc): Declare. * config/m68hc11/m68hc11.c (m68hc11_emit_libcall): Use LCT_CONST and don't pass operands[0] to emit_library_call_value. * config/m68hc11/m68hc11.md (tsthi_1): Use cpd for 68HC12. (zero_extendsi split): Simplify and use (zero_extendhi). (*addhi3): Remove 'w' constraint since stack pointer is handled by (addhi3_sp). (*ashlhi3_2): Operand 2 is clobbered use '+' for its constraint. (*ashlhi3, *ashrhi3, *lshrhi3): Likewise. (*ashrhi3_const): Fix shift by 7. (*lshrsi3_const16): Fix template. (call, call_value): Fix constraint and predicate. * config/m68hc11/m68hc11.md (X_REGNUM, D_REGNUM): New constant. (Y_REGNUM, SP_REGNUM, PC_REGNUM, A_REGNUM, B_REGNUM): Likewise. (CC_REGNUM): Likewise. (*unnamed splits): Use above constants instead of hard coded numbers. (*adcq, *subcq, *addsi_carry, *rotlqi3_with_carry): Likewise. (*rotlhi3_with_carry, *rotrhi3_with_carry): Likewise. (*return_16bit, *unnamed peepholes): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41802 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5941b0..8d5c1e7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,88 @@ +2001-05-03 Stephane Carrez + + * config/m68hc11/larith.asm (__mulqi3): Fix multiplication of two + negative numbers. + (___subdi3, ___adddi3): Use x instead of y as index register. + (__init_bss_section, __map_data_section): Optimize for 68HC12. + (__memset, __memcpy): Likewise. + (regs): Put the soft registers in bss for 68HC12. + (abort): Use trap to abort for 68hc12. + (__mulhi3, __mulhi32): Use emul for 68hc12. + (__mulsi3): Avoid to use the tmp soft register for 68hc12. + +2001-05-03 Stephane Carrez + + * config/m68hc11/m68hc11.h (LIMIT_RELOAD_CLASS): Don't define. + * config/m68hc11/m68hc11-protos.h (limit_reload_class): Remove. + * config/m68hc11/m68hc11.c (limit_reload_class): Remove. + (m68hc11_override_options): Remove setting of flag_no_nonansi_builtin. + Set 68HC12 min offset to -65536. + (print_operand): Put parenthesis arround the operand if it refers + to a symbol having the same name as a register. + (m68hc11_z_replacement): When z register is replaced by its + equivalent soft register, force the insn to be re-recognized. + (m68hc11_check_z_replacement): Fix the test when destination is + the index register and z dies in the insn. + (m68hc11_reorg): Remove the REG_DEAD notes beforce recomputing them. + +2001-05-03 Stephane Carrez + + * config/m68hc11/m68hc11.c (m68hc11_override_options): Initialize + costs according to processor variant. + (m68hc11_shift_cost): New function to compute shift costs. + (m68hc11_rtx_costs): Define costs according to processor variant. + (m6811_cost): Costs for 68HC11. + (m6812_cost): Costs for 68HC12. + (COSTS_N_INSNS): Remove. + + * config/m68hc11/m68hc11.h (RTX_COSTS): New. + (DEFAULT_RTX_COSTS): Remove. + (CONST_COSTS): Define costs according to OUTER_CODE. + (processor_costs): New struct to define costs. + (m68hc11_cost): Pointer to current costs. + +2001-05-03 Stephane Carrez + + * config/m68hc11/m68hc11.md (*addhi3_68hc12): Fix generation + and use m68hc11_notice_keep_cc when using leax/leay. + (addhi3 split): Reject split if the insn is handled by + leax/leay above. + * config/m68hc11/m68hc11.c (m68hc11_split_move): For 68HC12 the + push must be handled in a special way if the source operand uses + sp as index register. + (m68hc11_notice_keep_cc): New function. + (m68hc11_gen_movhi): Use it when an insn changes a register but + not the flags. + (m68hc11_gen_movqi): Fix move for 68HC12. + * config/m68hc11/m68hc11-protos.h (m68hc11_notice_keep_cc): Declare. + +2001-05-03 Stephane Carrez + + * config/m68hc11/m68hc11.c (m68hc11_emit_libcall): Use LCT_CONST + and don't pass operands[0] to emit_library_call_value. + +2001-05-03 Stephane Carrez + + * config/m68hc11/m68hc11.md (tsthi_1): Use cpd for 68HC12. + (zero_extendsi split): Simplify and use (zero_extendhi). + (*addhi3): Remove 'w' constraint since stack pointer is handled + by (addhi3_sp). + (*ashlhi3_2): Operand 2 is clobbered use '+' for its constraint. + (*ashlhi3, *ashrhi3, *lshrhi3): Likewise. + (*ashrhi3_const): Fix shift by 7. + (*lshrsi3_const16): Fix template. + (call, call_value): Fix constraint and predicate. + +2001-05-03 Stephane Carrez + + * config/m68hc11/m68hc11.md (X_REGNUM, D_REGNUM): New constant. + (Y_REGNUM, SP_REGNUM, PC_REGNUM, A_REGNUM, B_REGNUM): Likewise. + (CC_REGNUM): Likewise. + (*unnamed splits): Use above constants instead of hard coded numbers. + (*adcq, *subcq, *addsi_carry, *rotlqi3_with_carry): Likewise. + (*rotlhi3_with_carry, *rotrhi3_with_carry): Likewise. + (*return_16bit, *unnamed peepholes): Likewise. + 2001-05-03 David O'Brien * config.gcc(rs6000-ibm-aix|powerpc-ibm-aix): Do not include diff --git a/gcc/config/m68hc11/larith.asm b/gcc/config/m68hc11/larith.asm index e757729..fe70702 100644 --- a/gcc/config/m68hc11/larith.asm +++ b/gcc/config/m68hc11/larith.asm @@ -1,5 +1,5 @@ -/* libgcc1 routines for M68HC11. - Copyright (C) 1999, 2000 Free Software Foundation, Inc. +/* libgcc1 routines for M68HC11 & M68HC12. + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. This file is part of GNU CC. @@ -47,7 +47,11 @@ NAME: .word 0; \ /* Pseudo hard registers used by gcc. They must be located in page0. They will normally appear at the end of .page0 section. */ +#ifdef mc68hc12 + .sect .bss +#else .sect .page0 +#endif .globl _.tmp,_.frame .globl _.z,_.xy REG(_.tmp) @@ -61,7 +65,11 @@ REG(_.frame) /* Pseudo hard registers used by gcc. They must be located in page0. They will normally appear at the end of .page0 section. */ +#ifdef mc68hc12 + .sect .bss +#else .sect .page0 +#endif .globl _.d1,_.d2,_.d3,_.d4,_.d5,_.d6 .globl _.d7,_.d8 REG(_.d1) @@ -97,7 +105,11 @@ REG(_.d16) /* Pseudo hard registers used by gcc. They must be located in page0. They will normally appear at the end of .page0 section. */ +#ifdef mc68hc12 + .sect .bss +#else .sect .page0 +#endif .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22 .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28 .globl _.d29,_.d30,_.d31,_.d32 @@ -157,8 +169,12 @@ fatal: .globl abort abort: ldd #255 ; +#ifdef mc68hc12 + trap #0x30 +#else .byte 0xCD ; Generate an illegal instruction trap .byte 0x03 ; The simulator catches this and stops. +#endif jmp _exit #endif @@ -189,6 +205,23 @@ _cleanup: ;;; __memcpy: memcpy: +#ifdef mc68hc12 + ldx 2,sp + ldy 4,sp + pshd + xgdy + lsrd + bcc Start + movb 1,x+,1,y+ +Start: + beq Done +Loop: + movw 2,x+,2,y+ + dbne d,Loop +Done: + puld + rts +#else xgdy tsx ldd 4,x @@ -214,6 +247,7 @@ End: xgdy rts #endif +#endif #ifdef L_memset .sect .text @@ -237,6 +271,19 @@ End: #endif __memset: memset: +#ifdef mc68hc12 + xgdx + ldab val,sp + ldy size,sp + pshx + beq End +Loop: + stab 1,x+ + dbne y,Loop +End: + puld + rts +#else xgdx tsy ldab val,y @@ -253,6 +300,7 @@ End: xgdx rts #endif +#endif #ifdef L_adddi3 .sect .text @@ -260,29 +308,28 @@ End: ___adddi3: tsx - tsy pshb psha ldd 8,x - addd 16,y + addd 16,x pshb psha ldd 6,x - adcb 15,y - adca 14,y + adcb 15,x + adca 14,x pshb psha ldd 4,x - adcb 13,y - adca 12,y + adcb 13,x + adca 12,x pshb psha ldd 2,x - adcb 11,y - adca 10,y + adcb 11,x + adca 10,x tsx ldy 6,x @@ -303,29 +350,28 @@ ___adddi3: ___subdi3: tsx - tsy pshb psha ldd 8,x - subd 16,y + subd 16,x pshb psha ldd 6,x - sbcb 15,y - sbca 14,y + sbcb 15,x + sbca 14,x pshb psha ldd 4,x - sbcb 13,y - sbca 12,y + sbcb 13,x + sbca 12,x pshb psha ldd 2,x - sbcb 11,y - sbca 10,y + sbcb 11,x + sbca 10,x tsx ldy 6,x @@ -681,7 +727,6 @@ A_or_B_neg: addd #1 rts AB_neg: - nega negb mul rts @@ -699,6 +744,13 @@ AB_neg: ; b = register X ; ___mulhi3: +#ifdef mc68hc12 + pshx ; Preserve X + exg x,y + emul + exg x,y + pulx +#else stx *_.tmp pshb ldab *_.tmp+1 @@ -714,6 +766,7 @@ ___mulhi3: pulb mul ; A.low * B.low adda *_.tmp +#endif rts #endif @@ -750,6 +803,11 @@ ___mulhi3: ; 0,x ; __mulhi32: +#ifdef mc68hc12 + ldy 2,sp + emul + exg x,y +#else pshb psha tsx @@ -781,6 +839,7 @@ N: Ret: pshy pulx +#endif rts #endif @@ -823,7 +882,11 @@ __mulsi3: ; ; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low) ; +#ifdef mc68hc12 + cpx #0 +#else stx *_.tmp +#endif beq A_high_zero bsr ___mulhi3 ; A.high * B.low ; @@ -933,6 +996,10 @@ __map_data_section: ldx #__data_image ldy #__data_section_start Loop: +#ifdef mc68hc12 + movb 1,x+,1,y+ + dbne d,Loop +#else psha ldaa 0,x staa 0,y @@ -941,6 +1008,7 @@ Loop: iny subd #1 bne Loop +#endif Done: #endif @@ -955,10 +1023,15 @@ __init_bss_section: beq Done ldx #__bss_start Loop: +#ifdef mc68hc12 + clr 1,x+ + dbne d,Loop +#else clr 0,x inx subd #1 bne Loop +#endif Done: #endif diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h index 952e12b..8aaa76c 100644 --- a/gcc/config/m68hc11/m68hc11-protos.h +++ b/gcc/config/m68hc11/m68hc11-protos.h @@ -1,5 +1,5 @@ /* Prototypes for exported functions defined in m68hc11.c - Copyright (C) 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by Stephane Carrez (stcarrez@worldnet.fr) This file is part of GNU CC. @@ -70,6 +70,7 @@ extern int m68hc11_go_if_legitimate_address PARAMS((rtx, extern int m68hc11_legitimize_address PARAMS((rtx*, rtx, enum machine_mode)); extern void m68hc11_notice_update_cc PARAMS((rtx, rtx)); +extern void m68hc11_notice_keep_cc PARAMS((rtx)); extern void m68hc11_reorg PARAMS((rtx)); @@ -137,8 +138,6 @@ extern int hard_reg_operand PARAMS((rtx, enum machine_mode)); extern int soft_reg_operand PARAMS((rtx, enum machine_mode)); extern int reg_or_some_mem_operand PARAMS((rtx, enum machine_mode)); -extern enum reg_class limit_reload_class PARAMS((enum machine_mode, enum reg_class)); - #if defined TREE_CODE extern void m68hc11_init_cumulative_args PARAMS((CUMULATIVE_ARGS*, tree, diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c index 0075c39..99baa51 100644 --- a/gcc/config/m68hc11/m68hc11.c +++ b/gcc/config/m68hc11/m68hc11.c @@ -62,7 +62,7 @@ static int go_if_legitimate_address_internal PARAMS((rtx, enum machine_mode, static int register_indirect_p PARAMS((rtx, enum machine_mode, int)); static rtx m68hc11_expand_compare PARAMS((enum rtx_code, rtx, rtx)); static int must_parenthesize PARAMS ((rtx)); - +static int m68hc11_shift_cost PARAMS ((enum machine_mode, rtx, int)); static int m68hc11_auto_inc_p PARAMS ((rtx)); void create_regs_rtx PARAMS ((void)); @@ -120,6 +120,78 @@ rtx m68hc11_compare_op0; rtx m68hc11_compare_op1; +struct processor_costs *m68hc11_cost; + +/* Costs for a 68HC11. */ +struct processor_costs m6811_cost = { + /* add */ + COSTS_N_INSNS (2), + /* logical */ + COSTS_N_INSNS (2), + /* non-constant shift */ + COSTS_N_INSNS (20), + /* shiftQI const */ + { COSTS_N_INSNS (0), COSTS_N_INSNS (1), COSTS_N_INSNS (2), + COSTS_N_INSNS (3), COSTS_N_INSNS (4), COSTS_N_INSNS (3), + COSTS_N_INSNS (2), COSTS_N_INSNS (1) }, + + /* shiftHI const */ + { COSTS_N_INSNS (0), COSTS_N_INSNS (2), COSTS_N_INSNS (4), + COSTS_N_INSNS (6), COSTS_N_INSNS (8), COSTS_N_INSNS (6), + COSTS_N_INSNS (4), COSTS_N_INSNS (2), + COSTS_N_INSNS (2), COSTS_N_INSNS (4), + COSTS_N_INSNS (6), COSTS_N_INSNS (8), COSTS_N_INSNS (10), + COSTS_N_INSNS (8), COSTS_N_INSNS (6), COSTS_N_INSNS (4) + }, + /* mulQI */ + COSTS_N_INSNS (20), + /* mulHI */ + COSTS_N_INSNS (20 * 4), + /* mulSI */ + COSTS_N_INSNS (20 * 16), + /* divQI */ + COSTS_N_INSNS (20), + /* divHI */ + COSTS_N_INSNS (80), + /* divSI */ + COSTS_N_INSNS (100) +}; + +/* Costs for a 68HC12. */ +struct processor_costs m6812_cost = { + /* add */ + COSTS_N_INSNS (1), + /* logical */ + COSTS_N_INSNS (1), + /* non-constant shift */ + COSTS_N_INSNS (20), + /* shiftQI const */ + { COSTS_N_INSNS (0), COSTS_N_INSNS (1), COSTS_N_INSNS (2), + COSTS_N_INSNS (3), COSTS_N_INSNS (4), COSTS_N_INSNS (3), + COSTS_N_INSNS (2), COSTS_N_INSNS (1) }, + + /* shiftHI const */ + { COSTS_N_INSNS (0), COSTS_N_INSNS (2), COSTS_N_INSNS (4), + COSTS_N_INSNS (6), COSTS_N_INSNS (8), COSTS_N_INSNS (6), + COSTS_N_INSNS (4), COSTS_N_INSNS (2), + COSTS_N_INSNS (2), COSTS_N_INSNS (4), COSTS_N_INSNS (6), + COSTS_N_INSNS (8), COSTS_N_INSNS (10), COSTS_N_INSNS (8), + COSTS_N_INSNS (6), COSTS_N_INSNS (4) + }, + /* mulQI */ + COSTS_N_INSNS (3), + /* mulHI */ + COSTS_N_INSNS (3), + /* mulSI */ + COSTS_N_INSNS (3 * 4), + /* divQI */ + COSTS_N_INSNS (12), + /* divHI */ + COSTS_N_INSNS (12), + /* divSI */ + COSTS_N_INSNS (100) +}; + /* Machine specific options */ const char *m68hc11_regparm_string; @@ -130,24 +202,11 @@ static void m68hc11_add_gc_roots PARAMS ((void)); static int nb_soft_regs; -/* Flag defined in c-decl.c - - Nonzero means don't recognize the non-ANSI builtin functions. - -ansi sets this. - - It is set by 'm68hc11_override_options' to ensure that bcmp() and - bzero() are not defined. Their prototype are wrong and they - conflict with newlib definition. Don't define as external to - avoid a link problem for f77. */ -int flag_no_nonansi_builtin; - int m68hc11_override_options () { m68hc11_add_gc_roots (); - flag_no_nonansi_builtin = 1; - memset (m68hc11_reg_valid_for_index, 0, sizeof (m68hc11_reg_valid_for_index)); memset (m68hc11_reg_valid_for_base, 0, sizeof (m68hc11_reg_valid_for_base)); @@ -159,7 +218,8 @@ m68hc11_override_options () a -m68hc11 option was specified on the command line. */ if (TARGET_DEFAULT != MASK_M6811) target_flags &= ~TARGET_DEFAULT; - + + m68hc11_cost = &m6811_cost; m68hc11_min_offset = 0; m68hc11_max_offset = 256; m68hc11_index_reg_class = NO_REGS; @@ -176,7 +236,8 @@ m68hc11_override_options () /* Configure for a 68hc12 processor. */ if (TARGET_M6812) { - m68hc11_min_offset = 0; + m68hc11_cost = &m6812_cost; + m68hc11_min_offset = -65536; m68hc11_max_offset = 65536; m68hc11_index_reg_class = D_REGS; m68hc11_base_reg_class = A_OR_SP_REGS; @@ -278,29 +339,6 @@ hard_regno_mode_ok (regno, mode) } enum reg_class -limit_reload_class (mode, class) - enum machine_mode mode; - enum reg_class class; -{ - if (mode == Pmode) - { - if (class == m68hc11_base_reg_class || class == SP_REGS - || class == Y_REGS || class == X_REGS - || class == X_OR_SP_REGS || class == Y_OR_S_REGS - || class == A_OR_SP_REGS) - return class; - - if (debug_m6811) - { - printf ("Forcing to A_REGS\n"); - fflush (stdout); - } - return m68hc11_base_reg_class; - } - return class; -} - -enum reg_class preferred_reload_class (operand, class) rtx operand; enum reg_class class; @@ -733,13 +771,14 @@ m68hc11_emit_libcall (name, code, dmode, smode, noperands, operands) switch (noperands) { case 2: - ret = emit_library_call_value (libcall, NULL_RTX, 1, dmode, 1, - operands[1], smode); + ret = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, + dmode, 1, operands[1], smode); equiv = gen_rtx (code, dmode, operands[1]); break; case 3: - ret = emit_library_call_value (libcall, operands[0], 1, dmode, 2, + ret = emit_library_call_value (libcall, NULL_RTX, + LCT_CONST, dmode, 2, operands[1], smode, operands[2], smode); equiv = gen_rtx (code, dmode, operands[1], operands[2]); @@ -2125,9 +2164,19 @@ print_operand (file, op, letter) } else { + int need_parenthesize = 0; + if (letter != 'i') asm_fprintf (file, "%0I"); + else + need_parenthesize = must_parenthesize (op); + + if (need_parenthesize) + asm_fprintf (file, "("); + output_addr_const (file, op); + if (need_parenthesize) + asm_fprintf (file, ")"); } } @@ -2508,6 +2557,7 @@ m68hc11_split_move (to, from, scratch) rtx low_to, low_from; rtx high_to, high_from; enum machine_mode mode; + int offset = 0; mode = GET_MODE (to); if (GET_MODE_SIZE (mode) == 8) @@ -2517,6 +2567,22 @@ m68hc11_split_move (to, from, scratch) else mode = QImode; + if (TARGET_M6812 + && IS_STACK_PUSH (to) + && reg_mentioned_p (gen_rtx (REG, HImode, HARD_SP_REGNUM), from)) + { + if (mode == SImode) + { + offset = 4; + } + else if (mode == HImode) + { + offset = 2; + } + else + offset = 0; + } + low_to = m68hc11_gen_lowpart (mode, to); high_to = m68hc11_gen_highpart (mode, to); @@ -2531,6 +2597,11 @@ m68hc11_split_move (to, from, scratch) else high_from = m68hc11_gen_highpart (mode, from); + if (offset) + { + high_from = adj_offsettable_operand (high_from, offset); + low_from = high_from; + } if (mode == SImode) { m68hc11_split_move (low_to, low_from, scratch); @@ -2823,6 +2894,7 @@ m68hc11_gen_movhi (insn, operands) { if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1])) { + cc_status = cc_prev_status; switch (REGNO (operands[1])) { case HARD_X_REGNUM: @@ -2837,6 +2909,7 @@ m68hc11_gen_movhi (insn, operands) } if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0])) { + cc_status = cc_prev_status; switch (REGNO (operands[0])) { case HARD_X_REGNUM: @@ -2851,6 +2924,7 @@ m68hc11_gen_movhi (insn, operands) } if (H_REG_P (operands[0]) && H_REG_P (operands[1])) { + m68hc11_notice_keep_cc (operands[0]); output_asm_insn ("tfr\t%1,%0", operands); } else if (H_REG_P (operands[0])) @@ -2892,6 +2966,7 @@ m68hc11_gen_movhi (insn, operands) else { /* !!!! SCz wrong here. */ + fatal_insn ("Move insn not handled", insn); } } else @@ -2903,6 +2978,7 @@ m68hc11_gen_movhi (insn, operands) } else { + m68hc11_notice_keep_cc (operands[0]); output_asm_insn ("movw\t%1,%0", operands); } } @@ -2912,6 +2988,7 @@ m68hc11_gen_movhi (insn, operands) if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0])) { + cc_status = cc_prev_status; switch (REGNO (operands[0])) { case HARD_X_REGNUM: @@ -2947,7 +3024,7 @@ m68hc11_gen_movhi (insn, operands) } else { - cc_status = cc_prev_status; + m68hc11_notice_keep_cc (operands[0]); output_asm_insn ("pshx\n\tpula\n\tpulb", operands); } } @@ -3002,7 +3079,7 @@ m68hc11_gen_movhi (insn, operands) } else { - cc_status = cc_prev_status; + m68hc11_notice_keep_cc (operands[0]); output_asm_insn ("pshb", operands); output_asm_insn ("psha", operands); output_asm_insn ("pulx", operands); @@ -3058,7 +3135,7 @@ m68hc11_gen_movhi (insn, operands) case HARD_SP_REGNUM: if (D_REG_P (operands[1])) { - cc_status = cc_prev_status; + m68hc11_notice_keep_cc (operands[0]); output_asm_insn ("xgdx", operands); output_asm_insn ("txs", operands); output_asm_insn ("xgdx", operands); @@ -3099,6 +3176,7 @@ m68hc11_gen_movhi (insn, operands) if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1])) { + cc_status = cc_prev_status; switch (REGNO (operands[1])) { case HARD_X_REGNUM: @@ -3182,25 +3260,26 @@ m68hc11_gen_movqi (insn, operands) if (H_REG_P (operands[0]) && H_REG_P (operands[1])) { + m68hc11_notice_keep_cc (operands[0]); output_asm_insn ("tfr\t%1,%0", operands); } else if (H_REG_P (operands[0])) { if (Q_REG_P (operands[0])) - output_asm_insn ("lda%0\t%1", operands); + output_asm_insn ("lda%0\t%b1", operands); else if (D_REG_P (operands[0])) - output_asm_insn ("ldab\t%1", operands); + output_asm_insn ("ldab\t%b1", operands); else - output_asm_insn ("ld%0\t%1", operands); + goto m6811_move; } else if (H_REG_P (operands[1])) { if (Q_REG_P (operands[1])) - output_asm_insn ("sta%1\t%0", operands); + output_asm_insn ("sta%1\t%b0", operands); else if (D_REG_P (operands[1])) - output_asm_insn ("staa\t%0", operands); + output_asm_insn ("stab\t%b0", operands); else - output_asm_insn ("st%1\t%0", operands); + goto m6811_move; } else { @@ -3227,6 +3306,7 @@ m68hc11_gen_movqi (insn, operands) else { /* !!!! SCz wrong here. */ + fatal_insn ("Move insn not handled", insn); } } else @@ -3237,13 +3317,15 @@ m68hc11_gen_movqi (insn, operands) } else { - output_asm_insn ("movb\t%1,%0", operands); + m68hc11_notice_keep_cc (operands[0]); + output_asm_insn ("movb\t%b1,%b0", operands); } } } return; } + m6811_move: if (H_REG_P (operands[0])) { switch (REGNO (operands[0])) @@ -3618,6 +3700,24 @@ m68hc11_notice_update_cc (exp, insn) && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) cc_status.value2 = 0; } + +/* The current instruction does not affect the flags but changes + the register 'reg'. See if the previous flags can be kept for the + next instruction to avoid a comparison. */ +void +m68hc11_notice_keep_cc (reg) + rtx reg; +{ + if (reg == 0 + || cc_prev_status.value1 == 0 + || rtx_equal_p (reg, cc_prev_status.value1) + || (cc_prev_status.value2 + && reg_mentioned_p (reg, cc_prev_status.value2))) + CC_STATUS_INIT; + else + cc_status = cc_prev_status; +} + /* Machine Specific Reorg. */ @@ -3911,7 +4011,7 @@ m68hc11_check_z_replacement (insn, info) } info->x_used = 1; if (z_dies_here && !reg_mentioned_p (src, ix_reg) - && GET_CODE (src) == REG && REGNO (src) == HARD_X_REGNUM) + && GET_CODE (dst) == REG && REGNO (dst) == HARD_X_REGNUM) { info->need_save_z = 0; info->z_died = 1; @@ -3982,7 +4082,7 @@ m68hc11_check_z_replacement (insn, info) } info->y_used = 1; if (z_dies_here && !reg_mentioned_p (src, iy_reg) - && GET_CODE (src) == REG && REGNO (src) == HARD_Y_REGNUM) + && GET_CODE (dst) == REG && REGNO (dst) == HARD_Y_REGNUM) { info->need_save_z = 0; info->z_died = 1; @@ -4356,6 +4456,8 @@ m68hc11_z_replacement (insn) && INTVAL (src) == 0) { XEXP (body, 0) = gen_rtx (REG, GET_MODE (dst), SOFT_Z_REGNUM); + /* Force it to be re-recognized. */ + INSN_CODE (insn) = -1; return; } } @@ -4577,6 +4679,7 @@ m68hc11_reorg (first) rtx first; { int split_done = 0; + rtx insn; z_replacement_completed = 0; z_reg = gen_rtx (REG, HImode, HARD_Z_REGNUM); @@ -4602,6 +4705,28 @@ m68hc11_reorg (first) description to use the best assembly directives. */ if (optimize) { + /* Before recomputing the REG_DEAD notes, remove all of them. + This is necessary because the reload_cse_regs() pass can + have replaced some (MEM) with a register. In that case, + the REG_DEAD that could exist for that register may become + wrong. */ + for (insn = first; insn; insn = NEXT_INSN (insn)) + { + if (INSN_P (insn)) + { + rtx *pnote; + + pnote = ®_NOTES (insn); + while (*pnote != 0) + { + if (REG_NOTE_KIND (*pnote) == REG_DEAD) + *pnote = XEXP (*pnote, 1); + else + pnote = &XEXP (*pnote, 1); + } + } + } + find_basic_blocks (first, max_reg_num (), 0); life_analysis (first, 0, PROP_REG_INFO | PROP_DEATH_NOTES); } @@ -4651,8 +4776,6 @@ m68hc11_reorg (first) /* Cost functions. */ -#define COSTS_N_INSNS(N) ((N) * 4 - 2) - /* Cost of moving memory. */ int m68hc11_memory_move_cost (mode, class, in) @@ -4783,10 +4906,43 @@ m68hc11_address_cost (addr) return cost; } +static int +m68hc11_shift_cost (mode, x, shift) + enum machine_mode mode; + rtx x; + int shift; +{ + int total; + + total = rtx_cost (x, SET); + if (mode == QImode) + total += m68hc11_cost->shiftQI_const[shift % 8]; + else if (mode == HImode) + total += m68hc11_cost->shiftHI_const[shift % 16]; + else if (shift == 8 || shift == 16 || shift == 32) + total += m68hc11_cost->shiftHI_const[8]; + else if (shift != 0 && shift != 16 && shift != 32) + { + total += m68hc11_cost->shiftHI_const[1] * shift; + } + + /* For SI and others, the cost is higher. */ + if (GET_MODE_SIZE (mode) > 2) + total *= GET_MODE_SIZE (mode) / 2; + + /* When optimizing for size, make shift more costly so that + multiplications are prefered. */ + if (optimize_size && (shift % 8) != 0) + total *= 2; + + return total; +} + int m68hc11_rtx_costs (x, code, outer_code) rtx x; - enum rtx_code code, outer_code; + enum rtx_code code; + enum rtx_code outer_code ATTRIBUTE_UNUSED; { enum machine_mode mode = GET_MODE (x); int extra_cost = 0; @@ -4794,9 +4950,6 @@ m68hc11_rtx_costs (x, code, outer_code) switch (code) { - case MEM: - return m68hc11_address_cost (XEXP (x, 0)) + 4; - case ROTATE: case ROTATERT: case ASHIFT: @@ -4804,82 +4957,91 @@ m68hc11_rtx_costs (x, code, outer_code) case ASHIFTRT: if (GET_CODE (XEXP (x, 1)) == CONST_INT) { - int val = INTVAL (XEXP (x, 1)); - int cost; - - /* 8 or 16 shift instructions are fast. - Others are proportional to the shift counter. */ - if (val == 8 || val == 16 || val == -8 || val == -16) - { - val = 0; - } - cost = COSTS_N_INSNS (val + 1); - cost += rtx_cost (XEXP (x, 0), outer_code); - if (GET_MODE_SIZE (mode) >= 4 && val) - { - cost *= 4; - } - return cost; - } - total = rtx_cost (XEXP (x, 0), outer_code); - if (GET_MODE_SIZE (mode) >= 4) - { - total += COSTS_N_INSNS (16); - } - else - { - total += COSTS_N_INSNS (8); + return m68hc11_shift_cost (mode, XEXP (x, 0), INTVAL (XEXP (x, 1))); } + + total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code); + total += m68hc11_cost->shift_var; return total; - case MINUS: - case PLUS: case AND: case XOR: case IOR: - extra_cost = 0; + total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code); + total += m68hc11_cost->logical; - total = rtx_cost (XEXP (x, 0), outer_code) - + rtx_cost (XEXP (x, 1), outer_code); - if (GET_MODE_SIZE (mode) <= 2) - { - total += COSTS_N_INSNS (2); - } - else + /* Logical instructions are byte instructions only. */ + total *= GET_MODE_SIZE (mode); + return total; + + case MINUS: + case PLUS: + total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code); + total += m68hc11_cost->add; + if (GET_MODE_SIZE (mode) > 2) { - total += COSTS_N_INSNS (4); + total *= GET_MODE_SIZE (mode) / 2; } return total; + case UDIV: case DIV: case MOD: - if (mode == QImode || mode == HImode) - { - return 30; - } - else if (mode == SImode) - { - return 100; - } - else - { - return 150; - } - + total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code); + switch (mode) + { + case QImode: + total += m68hc11_cost->divQI; + break; + + case HImode: + total += m68hc11_cost->divHI; + break; + + case SImode: + default: + total += m68hc11_cost->divSI; + break; + } + return total; + case MULT: - if (mode == QImode) - { - return TARGET_OP_TIME ? 10 : 2; - } - if (mode == HImode) - { - return TARGET_OP_TIME ? 30 : 4; - } - if (mode == SImode) - { - return TARGET_OP_TIME ? 100 : 20; - } - return 150; + /* mul instruction produces 16-bit result. */ + if (mode == HImode && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND + && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) + return m68hc11_cost->multQI + + rtx_cost (XEXP (XEXP (x, 0), 0), code) + + rtx_cost (XEXP (XEXP (x, 1), 0), code); + + /* emul instruction produces 32-bit result for 68HC12. */ + if (TARGET_M6812 && mode == SImode + && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND + && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) + return m68hc11_cost->multHI + + rtx_cost (XEXP (XEXP (x, 0), 0), code) + + rtx_cost (XEXP (XEXP (x, 1), 0), code); + + total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code); + switch (mode) + { + case QImode: + total += m68hc11_cost->multQI; + break; + + case HImode: + total += m68hc11_cost->multHI; + break; + + case SImode: + if (GET_CODE (XEXP (x, 1)) == CONST_INT + && INTVAL (XEXP (x, 1)) == 65536) + break; + + default: + total += m68hc11_cost->multSI; + break; + } + return total; case NEG: case SIGN_EXTEND: @@ -4890,20 +5052,20 @@ m68hc11_rtx_costs (x, code, outer_code) case COMPARE: case ABS: case ZERO_EXTEND: - total = rtx_cost (XEXP (x, 0), outer_code); + total = extra_cost + rtx_cost (XEXP (x, 0), code); if (mode == QImode) { - return total + extra_cost + COSTS_N_INSNS (1); + return total + COSTS_N_INSNS (1); } if (mode == HImode) { - return total + extra_cost + COSTS_N_INSNS (2); + return total + COSTS_N_INSNS (2); } if (mode == SImode) { - return total + extra_cost + COSTS_N_INSNS (4); + return total + COSTS_N_INSNS (4); } - return total + extra_cost + COSTS_N_INSNS (8); + return total + COSTS_N_INSNS (8); case IF_THEN_ELSE: if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC) diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h index ba4eac7..475bf9c 100644 --- a/gcc/config/m68hc11/m68hc11.h +++ b/gcc/config/m68hc11/m68hc11.h @@ -207,6 +207,25 @@ extern const char *m68hc11_soft_reg_count; `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */ #define OVERRIDE_OPTIONS m68hc11_override_options (); + + +/* Define cost parameters for a given processor variant. */ +struct processor_costs { + int add; /* cost of an add instruction */ + int logical; /* cost of a logical instruction */ + int shift_var; + int shiftQI_const[8]; + int shiftHI_const[16]; + int multQI; + int multHI; + int multSI; + int divQI; + int divHI; + int divSI; +}; + +/* Costs for the current processor. */ +extern struct processor_costs *m68hc11_cost; /* target machine storage layout */ @@ -769,9 +788,6 @@ extern enum reg_class m68hc11_tmp_regs_class; #define PREFERRED_RELOAD_CLASS(X,CLASS) preferred_reload_class(X,CLASS) - -#define LIMIT_RELOAD_CLASS(MODE, CLASS) limit_reload_class(MODE,CLASS) - #define SMALL_REGISTER_CLASSES 1 /* A C expression whose value is nonzero if pseudos that have been @@ -1456,22 +1472,52 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER]; /* Compute the cost of computing a constant rtl expression RTX whose rtx-code is CODE. The body of this macro is a portion of a switch statement. If - the code is computed here, return it with a return statement. Otherwise, - break from the switch. */ -#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ - case CONST_INT: \ - if (RTX == const0_rtx) return 0; \ - case CONST: \ - return 0; \ - case LABEL_REF: \ - case SYMBOL_REF: \ - return 1; \ - case CONST_DOUBLE: \ + the code is computed here, return it with a return statement. Otherwise, + break from the switch. + + Constants are cheap. Moving them in registers must be avoided + because most instructions do not handle two register operands. */ +#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ + case CONST_INT: \ + /* Logical and arithmetic operations with a constant */ \ + /* operand are better because they are not supported */ \ + /* with two registers. */ \ + /* 'clr' is slow */ \ + if ((OUTER_CODE) == SET && (RTX) == const0_rtx) \ + return 1; \ + else \ + return 0; \ + case CONST: \ + case LABEL_REF: \ + case SYMBOL_REF: \ + if ((OUTER_CODE) == SET) \ + return 1; \ + return 0; \ + case CONST_DOUBLE: \ return 0; -#define DEFAULT_RTX_COSTS(X,CODE,OUTER_CODE) \ - return m68hc11_rtx_costs (X, CODE, OUTER_CODE); - +#define RTX_COSTS(X,CODE,OUTER_CODE) \ + case ROTATE: \ + case ROTATERT: \ + case ASHIFT: \ + case LSHIFTRT: \ + case ASHIFTRT: \ + case MINUS: \ + case PLUS: \ + case AND: \ + case XOR: \ + case IOR: \ + case UDIV: \ + case DIV: \ + case MOD: \ + case MULT: \ + case NEG: \ + case SIGN_EXTEND: \ + case NOT: \ + case COMPARE: \ + case ZERO_EXTEND: \ + case IF_THEN_ELSE: \ + return m68hc11_rtx_costs (X, CODE, OUTER_CODE); /* An expression giving the cost of an addressing mode that contains ADDRESS. If not defined, the cost is computed from the ADDRESS diff --git a/gcc/config/m68hc11/m68hc11.md b/gcc/config/m68hc11/m68hc11.md index 4cd495a..ec6956e 100644 --- a/gcc/config/m68hc11/m68hc11.md +++ b/gcc/config/m68hc11/m68hc11.md @@ -115,6 +115,24 @@ ;; Such split pattern must also be valid when z_replacement_completed == 2 ;; because flow/cse is not aware that D is composed of {a, b}. ;; +;; o Split patterns that generate a (mem:QI (symbol_reg _.dx)) to access +;; the high part of a soft register must be expanded after z_replacement +;; pass. +;; +;;--------------------------------------------------------------------------- +;; Constants + +(define_constants [ + ;; Register numbers + (X_REGNUM 0) ; Index X register + (D_REGNUM 1) ; Data register + (Y_REGNUM 2) ; Index Y register + (SP_REGNUM 3) ; Stack pointer + (PC_REGNUM 4) ; Program counter + (A_REGNUM 5) ; A (high part of D) + (B_REGNUM 6) ; B (low part of D) + (CC_REGNUM 7) ; Condition code register +]) ;;-------------------------------------------------------------------- ;;- Test @@ -156,7 +174,7 @@ "" "* { - if (D_REG_P (operands[0])) + if (D_REG_P (operands[0]) && !TARGET_M6812) return \"std\\t%t0\"; else return \"cp%0\\t#0\"; @@ -222,10 +240,10 @@ (use (match_operand:HI 1 "hard_reg_operand" "dxy")) (use (reg:HI 11))] "z_replacement_completed == 2" - [(set (mem:HI (pre_dec:HI (reg:HI 3))) (match_dup 1)) + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 1)) (set (match_dup 1) (match_dup 2)) (set (cc0) (match_dup 0)) - (set (match_dup 1) (mem:HI (post_inc:HI (reg:HI 3))))] + (set (match_dup 1) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] "operands[2] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") @@ -313,10 +331,10 @@ (use (match_operand:HI 2 "hard_reg_operand" "dxy")) (use (reg:HI 11))] "z_replacement_completed == 2" - [(set (mem:HI (pre_dec:HI (reg:HI 3))) (match_dup 2)) + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) (set (cc0) (compare (match_dup 0) (match_dup 1))) - (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI 3))))] + (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") ;; @@ -330,12 +348,12 @@ (compare (match_operand:QI 0 "hard_addr_reg_operand" "xy") (match_operand:QI 1 "cmp_operand" "uimA")))] "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode" - [(parallel [(set (reg:HI 1) (match_dup 3)) - (set (match_dup 3) (reg:HI 1))]) + [(parallel [(set (reg:HI D_REGNUM) (match_dup 3)) + (set (match_dup 3) (reg:HI D_REGNUM))]) (set (cc0) - (compare (reg:QI 1) (match_dup 1))) - (parallel [(set (reg:HI 1) (match_dup 3)) - (set (match_dup 3) (reg:HI 1))])] + (compare (reg:QI D_REGNUM) (match_dup 1))) + (parallel [(set (reg:HI D_REGNUM) (match_dup 3)) + (set (match_dup 3) (reg:HI D_REGNUM))])] "operands[3] = gen_rtx (REG, HImode, REGNO (operands[0]));") (define_split @@ -392,10 +410,10 @@ (use (match_operand:HI 2 "hard_reg_operand" "dxy")) (use (reg:HI 11))] "z_replacement_completed == 2" - [(set (mem:HI (pre_dec:HI (reg:HI 3))) (match_dup 2)) + [(set (mem:HI (pre_dec:HI (reg:HI SP_REGNUM))) (match_dup 2)) (set (match_dup 2) (match_dup 3)) (set (cc0) (compare (match_dup 0) (match_dup 1))) - (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI 3))))] + (set (match_dup 2) (mem:HI (post_inc:HI (reg:HI SP_REGNUM))))] "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);") (define_expand "cmpdf" @@ -703,11 +721,11 @@ "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode && !reg_mentioned_p (operands[0], operands[1]) && !D_REG_P (operands[1])" - [(parallel [(set (reg:HI 1) (match_dup 2)) - (set (match_dup 2) (reg:HI 1))]) - (set (reg:QI 1) (match_dup 1)) - (parallel [(set (reg:HI 1) (match_dup 2)) - (set (match_dup 2) (reg:HI 1))])] + [(parallel [(set (reg:HI D_REGNUM) (match_dup 2)) + (set (match_dup 2) (reg:HI D_REGNUM))]) + (set (reg:QI D_REGNUM) (match_dup 1)) + (parallel [(set (reg:HI D_REGNUM) (match_dup 2)) + (set (match_dup 2) (reg:HI D_REGNUM))])] "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));") ;; @@ -719,11 +737,11 @@ "z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode && !reg_mentioned_p (operands[1], operands[0]) && !D_REG_P (operands[0])" - [(parallel [(set (reg:HI 1) (match_dup 2)) - (set (match_dup 2) (reg:HI 1))]) - (set (match_dup 0) (reg:QI 1)) - (parallel [(set (reg:HI 1) (match_dup 2)) - (set (match_dup 2) (reg:HI 1))])] + [(parallel [(set (reg:HI D_REGNUM) (match_dup 2)) + (set (match_dup 2) (reg:HI D_REGNUM))]) + (set (match_dup 0) (reg:QI D_REGNUM)) + (parallel [(set (reg:HI D_REGNUM) (match_dup 2)) + (set (match_dup 2) (reg:HI D_REGNUM))])] "operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));") (define_insn "*movqi2_push" @@ -1048,15 +1066,11 @@ [(set (match_operand:SI 0 "non_push_operand" "=mu") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dxy")))] "reload_completed && !X_REG_P (operands[0])" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (const_int 0)) - (set (match_dup 5) (const_int 0))] + [(set (match_dup 2) (zero_extend:HI (match_dup 1))) + (set (match_dup 3) (const_int 0))] " operands[2] = m68hc11_gen_lowpart (HImode, operands[0]); - operands[3] = gen_rtx (REG, HImode, REGNO (operands[1])); - operands[4] = m68hc11_gen_lowpart (HImode, operands[0]); - operands[4] = m68hc11_gen_highpart (QImode, operands[4]); - operands[5] = m68hc11_gen_highpart (HImode, operands[0]);") + operands[3] = m68hc11_gen_highpart (HImode, operands[0]);") (define_split [(set (match_operand:SI 0 "hard_reg_operand" "=D") @@ -1320,8 +1334,8 @@ [(set (match_operand:SI 0 "register_operand" "=D") (sign_extend:SI (match_operand:HI 1 "register_operand" "A")))] "reload_completed && (Y_REG_P (operands[1]) || Z_REG_P (operands[1]))" - [(set (reg:HI 1) (match_dup 1)) - (set (match_dup 0) (sign_extend:SI (reg:HI 1)))] + [(set (reg:HI D_REGNUM) (match_dup 1)) + (set (match_dup 0) (sign_extend:SI (reg:HI D_REGNUM)))] "") (define_insn "extendhisi2" @@ -1409,13 +1423,13 @@ (match_dup 0))) (clobber (match_scratch:HI 1 "=X"))] "reload_completed && z_replacement_completed == 2" - [(set (reg:HI 1) (ashift:HI (reg:HI 1) (const_int 1))) - (parallel [(set (reg:HI 1) (reg:HI 0)) - (set (reg:HI 0) (reg:HI 1))]) - (set (reg:QI 6) (rotate:QI (reg:QI 6) (reg:QI 7))) - (set (reg:QI 5) (rotate:QI (reg:QI 5) (reg:QI 7))) - (parallel [(set (reg:HI 1) (reg:HI 0)) - (set (reg:HI 0) (reg:HI 1))])] + [(set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1))) + (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))]) + (set (reg:QI B_REGNUM) (rotate:QI (reg:QI B_REGNUM) (reg:QI CC_REGNUM))) + (set (reg:QI A_REGNUM) (rotate:QI (reg:QI A_REGNUM) (reg:QI CC_REGNUM))) + (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])] "") @@ -1472,9 +1486,9 @@ (match_operand:SI 2 "memory_operand" "m,m"))) (clobber (match_scratch:HI 3 "=X,X"))] "reload_completed" - [(set (reg:HI 1) (zero_extend:HI (match_dup 1))) + [(set (reg:HI D_REGNUM) (zero_extend:HI (match_dup 1))) (parallel [(set (match_dup 0) - (plus:SI (zero_extend:SI (reg:HI 1)) (match_dup 2))) + (plus:SI (zero_extend:SI (reg:HI D_REGNUM)) (match_dup 2))) (clobber (match_dup 3))])] "") @@ -1658,7 +1672,7 @@ (clobber (match_scratch:HI 3 "=X"))] "reload_completed && z_replacement_completed == 2 && ((INTVAL (operands[2]) & 0x0FFFF) == 0)" - [(set (reg:HI 0) (plus:HI (reg:HI 0) (match_dup 3)))] + [(set (reg:HI X_REGNUM) (plus:HI (reg:HI X_REGNUM) (match_dup 3)))] "operands[3] = m68hc11_gen_highpart (HImode, operands[2]);") (define_split @@ -1669,13 +1683,13 @@ "reload_completed && z_replacement_completed == 2 && (GET_CODE (operands[2]) != CONST_INT || (!(INTVAL (operands[2]) >= -65536 && INTVAL (operands[2]) <= 65535)))" - [(set (reg:HI 1) (plus:HI (reg:HI 1) (match_dup 3))) - (parallel [(set (reg:HI 1) (reg:HI 0)) - (set (reg:HI 0) (reg:HI 1))]) - (set (reg:QI 6) (plus:QI (plus:QI (reg:QI 7) (reg:QI 6)) (match_dup 4))) - (set (reg:QI 5) (plus:QI (plus:QI (reg:QI 7) (reg:QI 5)) (match_dup 5))) - (parallel [(set (reg:HI 1) (reg:HI 0)) - (set (reg:HI 0) (reg:HI 1))])] + [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3))) + (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))]) + (set (reg:QI B_REGNUM) (plus:QI (plus:QI (reg:QI CC_REGNUM) (reg:QI B_REGNUM)) (match_dup 4))) + (set (reg:QI A_REGNUM) (plus:QI (plus:QI (reg:QI CC_REGNUM) (reg:QI A_REGNUM)) (match_dup 5))) + (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])] "operands[3] = m68hc11_gen_lowpart (HImode, operands[2]); operands[4] = m68hc11_gen_highpart (HImode, operands[2]); operands[5] = m68hc11_gen_highpart (QImode, operands[4]); @@ -1689,7 +1703,7 @@ [(set (match_operand:HI 0 "register_operand" "=x") (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "0") (const_int 0)) - (reg:HI 7)))] + (reg:HI CC_REGNUM)))] "" "* { @@ -1746,25 +1760,39 @@ "") (define_insn "*addhi3_68hc12" - [(set (match_operand:HI 0 "register_operand" "=d,A*w,A*w") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0,Aw") - (match_operand:HI 2 "general_operand" "imA*wu,id,id")))] + [(set (match_operand:HI 0 "register_operand" "=*d,A*w,A*w,A") + (plus:HI (match_operand:HI 1 "register_operand" "%0,0,Aw,0") + (match_operand:HI 2 "general_operand" "imA*wu,id,id,!muA")))] "TARGET_M6812" "* { int val; const char* insn_code; + if (which_alternative >= 3) + { + if (A_REG_P (operands[2])) + { + CC_STATUS_INIT; + output_asm_insn (\"xgd%2\", operands); + output_asm_insn (\"lea%0 d,%0\", operands); + return \"xgd%2\"; + } + return \"#\"; + } + if (D_REG_P (operands[0])) { if (X_REG_P (operands[2])) { + m68hc11_notice_keep_cc (operands[0]); output_asm_insn (\"xgdx\", operands); output_asm_insn (\"leax\\td,%2\", operands); return \"xgdx\"; } else if (Y_REG_P (operands[2])) { + m68hc11_notice_keep_cc (operands[0]); output_asm_insn (\"xgdy\", operands); output_asm_insn (\"leay\\td,%2\", operands); return \"xgdy\"; @@ -1784,7 +1812,7 @@ if (val != -1 || val != 1 || !rtx_equal_p (operands[0], operands[1])) { - cc_status = cc_prev_status; + m68hc11_notice_keep_cc (operands[0]); switch (REGNO (operands[0])) { case HARD_X_REGNUM: @@ -1922,9 +1950,9 @@ "") (define_insn "*addhi3" - [(set (match_operand:HI 0 "hard_reg_operand" "=A,d,!A,d*A,!d,!w") - (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0") - (match_operand:HI 2 "general_operand" "N,i,I,umi*A*d,!*d*w,i")))] + [(set (match_operand:HI 0 "hard_reg_operand" "=A,d,!A,d*A,!d") + (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0") + (match_operand:HI 2 "general_operand" "N,i,I,umi*A*d,!*d*w")))] "TARGET_M6811" "* { @@ -2110,7 +2138,7 @@ ;; (define_insn "*adcq" [(set (match_operand:QI 0 "register_operand" "=q") - (plus:QI (plus:QI (reg:QI 7) + (plus:QI (plus:QI (reg:QI CC_REGNUM) (match_operand:QI 1 "register_operand" "%0")) (match_operand:QI 2 "general_operand" "ium")))] "" @@ -2201,13 +2229,13 @@ (clobber (match_scratch:HI 3 "=X"))] "reload_completed && z_replacement_completed == 2 && X_REG_P (operands[1])" - [(set (reg:HI 1) (minus:HI (reg:HI 1) (match_dup 3))) - (parallel [(set (reg:HI 0) (reg:HI 1)) - (set (reg:HI 1) (reg:HI 0))]) - (set (reg:QI 6) (minus:QI (minus:QI (reg:QI 7) (reg:QI 6)) (match_dup 4))) - (set (reg:QI 5) (minus:QI (minus:QI (reg:QI 7) (reg:QI 5)) (match_dup 5))) - (parallel [(set (reg:HI 0) (reg:HI 1)) - (set (reg:HI 1) (reg:HI 0))])] + [(set (reg:HI D_REGNUM) (minus:HI (reg:HI D_REGNUM) (match_dup 3))) + (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))]) + (set (reg:QI B_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI B_REGNUM)) (match_dup 4))) + (set (reg:QI A_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI A_REGNUM)) (match_dup 5))) + (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])] "operands[3] = m68hc11_gen_lowpart (HImode, operands[2]); operands[4] = m68hc11_gen_highpart (HImode, operands[2]); operands[5] = m68hc11_gen_highpart (QImode, operands[4]); @@ -2220,13 +2248,13 @@ (clobber (match_scratch:HI 3 "=X"))] "reload_completed && z_replacement_completed == 2 && X_REG_P (operands[2])" - [(set (reg:HI 1) (minus:HI (reg:HI 1) (match_dup 3))) - (parallel [(set (reg:HI 0) (reg:HI 1)) - (set (reg:HI 1) (reg:HI 0))]) - (set (reg:QI 6) (minus:QI (minus:QI (reg:QI 7) (reg:QI 6)) (match_dup 4))) - (set (reg:QI 5) (minus:QI (minus:QI (reg:QI 7) (reg:QI 5)) (match_dup 5))) - (parallel [(set (reg:HI 0) (reg:HI 1)) - (set (reg:HI 1) (reg:HI 0))]) + [(set (reg:HI D_REGNUM) (minus:HI (reg:HI D_REGNUM) (match_dup 3))) + (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))]) + (set (reg:QI B_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI B_REGNUM)) (match_dup 4))) + (set (reg:QI A_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI A_REGNUM)) (match_dup 5))) + (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))]) (set (reg:SI 0) (neg:SI (reg:SI 0)))] "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]); operands[4] = m68hc11_gen_highpart (HImode, operands[1]); @@ -2365,7 +2393,7 @@ ;; (define_insn "*subcq" [(set (match_operand:QI 0 "register_operand" "=q") - (minus:QI (minus:QI (reg:QI 7) + (minus:QI (minus:QI (reg:QI CC_REGNUM) (match_operand:QI 1 "register_operand" "0")) (match_operand:QI 2 "general_operand" "ium")))] "" @@ -2927,10 +2955,10 @@ (match_operand:QI 1 "general_operand" "dxy,imu")) (match_operand:SI 2 "general_operand" "imuD,imuD")]))] "z_replacement_completed == 2" - [(set (reg:QI 5) (match_dup 4)) - (set (reg:QI 1) (match_dup 7)) - (set (reg:QI 6) (match_op_dup 3 [(reg:QI 6) (match_dup 5)])) - (set (reg:HI 0) (match_dup 6))] + [(set (reg:QI A_REGNUM) (match_dup 4)) + (set (reg:QI D_REGNUM) (match_dup 7)) + (set (reg:QI B_REGNUM) (match_op_dup 3 [(reg:QI B_REGNUM) (match_dup 5)])) + (set (reg:HI X_REGNUM) (match_dup 6))] "PUT_MODE (operands[3], QImode); if (X_REG_P (operands[2])) { @@ -2957,9 +2985,9 @@ (match_operand:HI 1 "general_operand" "dA,imu")) (match_operand:SI 2 "general_operand" "imuD,imuD")]))] "reload_completed" - [(set (reg:HI 1) (match_dup 4)) - (set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 5)])) - (set (reg:HI 0) (match_dup 6))] + [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) + (set (reg:HI X_REGNUM) (match_dup 6))] "PUT_MODE (operands[3], HImode); if (X_REG_P (operands[2])) { @@ -3003,9 +3031,9 @@ (match_operand:QI 1 "general_operand" "imud")) (match_operand:HI 2 "general_operand" "dimu")]))] "z_replacement_completed == 2" - [(set (reg:QI 6) (match_dup 6)) - (set (reg:QI 5) (match_dup 4)) - (set (reg:QI 6) (match_op_dup 3 [(reg:QI 6) (match_dup 5)]))] + [(set (reg:QI B_REGNUM) (match_dup 6)) + (set (reg:QI A_REGNUM) (match_dup 4)) + (set (reg:QI B_REGNUM) (match_op_dup 3 [(reg:QI B_REGNUM) (match_dup 5)]))] " PUT_MODE (operands[3], QImode); if (D_REG_P (operands[2])) @@ -3034,8 +3062,8 @@ (match_operand:HI 2 "general_operand" "dimu") (const_int 8))]))] "z_replacement_completed == 2" - [(set (reg:QI 6) (match_dup 5)) - (set (reg:QI 5) (match_dup 4))] + [(set (reg:QI A_REGNUM) (match_dup 4)) + (set (reg:QI B_REGNUM) (match_dup 5))] " if (GET_CODE (operands[3]) == AND) { @@ -3074,9 +3102,9 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "uim,0")]))] "reload_completed" - [(set (reg:HI 1) (match_dup 4)) - (set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 5)])) - (set (reg:HI 0) (match_dup 6))] + [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)])) + (set (reg:HI X_REGNUM) (match_dup 6))] "operands[5] = m68hc11_gen_highpart (HImode, operands[1]); if (X_REG_P (operands[2])) { @@ -3110,11 +3138,11 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "0,0")]))] "z_replacement_completed == 2" - [(parallel [(set (reg:HI 1) (reg:HI 0)) - (set (reg:HI 0) (reg:HI 1))]) - (set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 4)])) - (parallel [(set (reg:HI 1) (reg:HI 0)) - (set (reg:HI 0) (reg:HI 1))])] + [(parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 4)])) + (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM)) + (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])] "operands[4] = m68hc11_gen_lowpart (HImode, operands[1]); PUT_MODE (operands[3], HImode);") @@ -3177,17 +3205,19 @@ /* If we are adding a small constant to X or Y, it's better to use one or several inx/iny instructions. */ && !(GET_CODE (operands[3]) == PLUS - && (TARGET_M6812 + && ((TARGET_M6812 + && (immediate_operand (operands[2], HImode) + || hard_reg_operand (operands[2], HImode))) || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= -4 && INTVAL (operands[2]) <= 4)))" [(set (match_dup 4) (match_dup 5)) (set (match_dup 8) (match_dup 7)) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 6)])) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 6)])) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] " /* Save the operand2 in a temporary location and use it. */ if (H_REG_P (operands[2]) @@ -3224,16 +3254,18 @@ /* If we are adding a small constant to X or Y, it's better to use one or several inx/iny instructions. */ && !(GET_CODE (operands[3]) == PLUS - && (TARGET_M6812 + && ((TARGET_M6812 + && (immediate_operand (operands[2], HImode) + || hard_reg_operand (operands[2], HImode))) || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= -4 && INTVAL (operands[2]) <= 4)))" [(set (match_dup 0) (match_dup 1)) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 2)])) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 2)])) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] " ") @@ -3283,11 +3315,11 @@ [(match_operand 1 "general_operand" "uim*d*A")]))] "z_replacement_completed == 2" [(set (match_dup 4) (match_dup 5)) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:HI 1) (match_op_dup 2 [(match_dup 3)])) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) (match_op_dup 2 [(match_dup 3)])) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] " { if ((H_REG_P (operands[1]) @@ -3331,11 +3363,11 @@ && GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == -1))" [(set (match_dup 5) (match_dup 6)) - (parallel [(set (reg:HI 1) (match_dup 4)) - (set (match_dup 4) (reg:HI 1))]) - (set (reg:QI 1) (match_op_dup 3 [(reg:QI 1) (match_dup 7)])) - (parallel [(set (reg:HI 1) (match_dup 4)) - (set (match_dup 4) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (match_dup 4) (reg:HI D_REGNUM))]) + (set (reg:QI D_REGNUM) (match_op_dup 3 [(reg:QI D_REGNUM) (match_dup 7)])) + (parallel [(set (reg:HI D_REGNUM) (match_dup 4)) + (set (match_dup 4) (reg:HI D_REGNUM))])] "operands[4] = gen_rtx (REG, HImode, REGNO (operands[0])); /* For the second operand is a hard register or if the address @@ -3410,11 +3442,11 @@ [(match_operand:QI 1 "general_operand" "uim*d*x*y")]))] "z_replacement_completed == 2" [(set (match_dup 4) (match_dup 5)) - (parallel [(set (reg:HI 1) (match_dup 3)) - (set (match_dup 3) (reg:HI 1))]) - (set (reg:QI 1) (match_op_dup 2 [(match_dup 6)])) - (parallel [(set (reg:HI 1) (match_dup 3)) - (set (match_dup 3) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 3)) + (set (match_dup 3) (reg:HI D_REGNUM))]) + (set (reg:QI D_REGNUM) (match_op_dup 2 [(match_dup 6)])) + (parallel [(set (reg:HI D_REGNUM) (match_dup 3)) + (set (match_dup 3) (reg:HI D_REGNUM))])] " { operands[3] = gen_rtx (REG, HImode, REGNO (operands[0])); @@ -3530,12 +3562,12 @@ (not:SI (match_operand:SI 1 "non_push_operand" "0")))] "z_replacement_completed == 2 && (!D_REG_P (operands[0]) || (optimize && optimize_size == 0))" - [(set (reg:HI 1) (not:HI (reg:HI 1))) - (parallel [(set (reg:HI 0) (reg:HI 1)) - (set (reg:HI 1) (reg:HI 0))]) - (set (reg:HI 1) (not:HI (reg:HI 1))) - (parallel [(set (reg:HI 0) (reg:HI 1)) - (set (reg:HI 1) (reg:HI 0))])] + [(set (reg:HI D_REGNUM) (not:HI (reg:HI D_REGNUM))) + (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))]) + (set (reg:HI D_REGNUM) (not:HI (reg:HI D_REGNUM))) + (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])] " { /* The result pattern only works for D register. @@ -3623,15 +3655,15 @@ (set (match_dup 4) (match_dup 2)) (set (match_dup 2) (match_dup 5)) - (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI 7))) + (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI CC_REGNUM))) (set (match_dup 6) (match_dup 2)) (set (match_dup 2) (match_dup 7)) - (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI 7))) + (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI CC_REGNUM))) (set (match_dup 8) (match_dup 2)) (set (match_dup 2) (match_dup 9)) - (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI 7))) + (set (match_dup 2) (rotate:HI (match_dup 2) (reg:HI CC_REGNUM))) (set (match_dup 10) (match_dup 2))] "operands[3] = m68hc11_gen_lowpart (SImode, operands[1]); operands[5] = m68hc11_gen_highpart (HImode, operands[3]); @@ -3663,8 +3695,8 @@ (const_int 16)) (match_operand:SI 2 "general_operand" "0")))] "z_replacement_completed == 2" - [(set (reg:HI 1) (plus:HI (reg:HI 1) (match_dup 3))) - (set (reg:HI 0) (plus:HI (plus:HI (reg:HI 0) (const_int 0)) (reg:HI 7)))] + [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3))) + (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))] "operands[3] = m68hc11_gen_highpart (HImode, operands[1]);") (define_insn "addsi_ashift16" @@ -3685,7 +3717,7 @@ (match_operand:SI 1 "general_operand" "0"))) (clobber (match_scratch:HI 3 "=X"))] "0 && reload_completed && z_replacement_completed == 2" - [(set (reg:HI 0) (plus:HI (reg:HI 0) (match_dup 4)))] + [(set (reg:HI X_REGNUM) (plus:HI (reg:HI X_REGNUM) (match_dup 4)))] " { operands[4] = m68hc11_gen_lowpart (HImode, operands[2]); @@ -3705,8 +3737,8 @@ (const_int 65535)) (match_operand:SI 2 "general_operand" "0")))] "z_replacement_completed == 2" - [(set (reg:HI 1) (plus:HI (reg:HI 1) (match_dup 3))) - (set (reg:HI 0) (plus:HI (plus:HI (reg:HI 0) (const_int 0)) (reg:HI 7)))] + [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3))) + (set (reg:HI X_REGNUM) (plus:HI (plus:HI (reg:HI X_REGNUM) (const_int 0)) (reg:HI CC_REGNUM)))] "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]);") ;; @@ -3766,8 +3798,8 @@ (const_int 16))) (clobber (match_scratch:HI 2 "=X"))] "reload_completed" - [(set (reg:HI 0) (match_dup 1)) - (set (reg:HI 1) (const_int 0))] + [(set (reg:HI X_REGNUM) (match_dup 1)) + (set (reg:HI D_REGNUM) (const_int 0))] "") (define_insn "*ashlsi3_const1" @@ -3910,7 +3942,7 @@ (define_insn "*ashlhi3_2" [(set (match_operand:HI 0 "register_operand" "=d") (ashift:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "register_operand" "x"))) + (match_operand:HI 2 "register_operand" "+x"))) (clobber (match_dup 2))] "" "* @@ -3919,10 +3951,10 @@ return \"bsr\\t___lshlhi3\"; }") -(define_insn "" +(define_insn "*ashlhi3" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) (ashift:HI (match_dup 0) - (match_operand:HI 1 "register_operand" "x"))) + (match_operand:HI 1 "register_operand" "+x"))) (clobber (match_dup 1))] "" "* @@ -4177,9 +4209,9 @@ output_asm_insn (\"rolb\", operands); output_asm_insn (\"rola\", operands); output_asm_insn (\"tab\", operands); - output_asm_insn (\"anda\\t#1\", operands); + output_asm_insn (\"anda\\t#0\", operands); output_asm_insn (\"bcc\\t%l0\", ops); - output_asm_insn (\"oraa\\t#0xFE\", ops); + output_asm_insn (\"coma\", ops); ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (ops[0])); @@ -4199,7 +4231,7 @@ (define_insn "*ashrhi3" [(set (match_operand:HI 0 "register_operand" "=d,x") (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "register_operand" "x,d"))) + (match_operand:HI 2 "register_operand" "+x,+d"))) (clobber (match_dup 2))] "" "* @@ -4387,14 +4419,14 @@ (match_operand:DI 2 "const_int_operand" ""))) (clobber (match_scratch:HI 3 "=d"))] "z_replacement_completed && INTVAL (operands[2]) >= 56" - [(set (reg:QI 1) (match_dup 9)) - (set (reg:QI 1) (lshiftrt:QI (reg:QI 1) (match_dup 8))) - (set (reg:HI 1) (zero_extend:HI (reg:QI 1))) - (set (match_dup 4) (reg:HI 1)) - (set (reg:QI 1) (const_int 0)) - (set (match_dup 5) (reg:HI 1)) - (set (match_dup 6) (reg:HI 1)) - (set (match_dup 7) (reg:HI 1))] + [(set (reg:QI D_REGNUM) (match_dup 9)) + (set (reg:QI D_REGNUM) (lshiftrt:QI (reg:QI D_REGNUM) (match_dup 8))) + (set (reg:HI D_REGNUM) (zero_extend:HI (reg:QI D_REGNUM))) + (set (match_dup 4) (reg:HI D_REGNUM)) + (set (reg:QI D_REGNUM) (const_int 0)) + (set (match_dup 5) (reg:HI D_REGNUM)) + (set (match_dup 6) (reg:HI D_REGNUM)) + (set (match_dup 7) (reg:HI D_REGNUM))] "operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 56); operands[4] = m68hc11_gen_lowpart (SImode, operands[0]); operands[5] = m68hc11_gen_highpart (HImode, operands[4]); @@ -4415,13 +4447,13 @@ (clobber (match_scratch:HI 3 "=d"))] "z_replacement_completed && INTVAL (operands[2]) >= 48 && INTVAL (operands[2]) < 56" - [(set (reg:HI 1) (match_dup 9)) - (set (reg:HI 1) (lshiftrt:HI (reg:HI 1) (match_dup 8))) - (set (match_dup 4) (reg:HI 1)) - (set (reg:HI 1) (const_int 0)) - (set (match_dup 5) (reg:HI 1)) - (set (match_dup 6) (reg:HI 1)) - (set (match_dup 7) (reg:HI 1))] + [(set (reg:HI D_REGNUM) (match_dup 9)) + (set (reg:HI D_REGNUM) (lshiftrt:HI (reg:HI D_REGNUM) (match_dup 8))) + (set (match_dup 4) (reg:HI D_REGNUM)) + (set (reg:HI D_REGNUM) (const_int 0)) + (set (match_dup 5) (reg:HI D_REGNUM)) + (set (match_dup 6) (reg:HI D_REGNUM)) + (set (match_dup 7) (reg:HI D_REGNUM))] "operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 48); operands[4] = m68hc11_gen_lowpart (SImode, operands[0]); operands[5] = m68hc11_gen_highpart (HImode, operands[4]); @@ -4452,15 +4484,15 @@ (set (match_dup 4) (match_dup 2)) (set (match_dup 2) (match_dup 5)) - (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI 7))) + (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI CC_REGNUM))) (set (match_dup 6) (match_dup 2)) (set (match_dup 2) (match_dup 7)) - (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI 7))) + (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI CC_REGNUM))) (set (match_dup 8) (match_dup 2)) (set (match_dup 2) (match_dup 9)) - (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI 7))) + (set (match_dup 2) (rotatert:HI (match_dup 2) (reg:HI CC_REGNUM))) (set (match_dup 10) (match_dup 2))] "operands[3] = m68hc11_gen_highpart (SImode, operands[1]); operands[5] = m68hc11_gen_lowpart (HImode, operands[3]); @@ -4508,8 +4540,10 @@ (const_int 16))) (clobber (match_scratch:HI 2 "=X,X,X,X"))] "" - "# + "@ + # xgdx\\n\\tldx\\t#0 + # #") (define_insn "*lshrsi3_const1" @@ -4727,7 +4761,7 @@ (define_insn "*lshrhi3" [(set (match_operand:HI 0 "register_operand" "=d,x") (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:HI 2 "register_operand" "x,d"))) + (match_operand:HI 2 "register_operand" "+x,+d"))) (clobber (match_dup 2))] "" "* @@ -4868,7 +4902,7 @@ (define_insn "*rotlqi3_with_carry" [(set (match_operand:QI 0 "register_operand" "=d,!q") (rotate:QI (match_operand:QI 1 "register_operand" "0,0") - (reg:QI 7)))] + (reg:QI CC_REGNUM)))] "" "* { @@ -4881,7 +4915,7 @@ (define_insn "*rotlhi3_with_carry" [(set (match_operand:HI 0 "register_operand" "=d") (rotate:HI (match_operand:HI 1 "register_operand" "0") - (reg:HI 7)))] + (reg:HI CC_REGNUM)))] "" "* { @@ -4892,7 +4926,7 @@ (define_insn "*rotrhi3_with_carry" [(set (match_operand:HI 0 "register_operand" "=d") (rotatert:HI (match_operand:HI 1 "register_operand" "0") - (reg:HI 7)))] + (reg:HI CC_REGNUM)))] "" "* { @@ -5328,7 +5362,7 @@ ;; ;;- Call a function that returns no value. (define_insn "call" - [(call (match_operand:QI 0 "memory_operand" "mAi") + [(call (match_operand:QI 0 "memory_operand" "m") (match_operand:SI 1 "general_operand" "g"))] ;; Operand 1 not really used on the m68hc11. "" @@ -5349,7 +5383,7 @@ (define_insn "call_value" [(set (match_operand 0 "" "=g") - (call (match_operand:QI 1 "general_operand" "mAi") + (call (match_operand:QI 1 "memory_operand" "m") (match_operand:SI 2 "general_operand" "g")))] "" "* @@ -5478,7 +5512,7 @@ (define_insn "*return_16bit" [(return) - (use (reg:HI 1))] + (use (reg:HI D_REGNUM))] "reload_completed && m68hc11_total_frame_size () == 0" "* { @@ -5545,13 +5579,13 @@ (define_peephole [(set (match_operand:HI 0 "hard_reg_operand" "xy") (match_operand:HI 1 "const_int_operand" "")) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:HI 1) - (plus (reg:HI 1) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) + (plus (reg:HI D_REGNUM) (match_operand:HI 2 "general_operand" ""))) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] "(INTVAL (operands[1]) & 0x0FF) == 0" "* { @@ -5634,9 +5668,9 @@ ;; (set ...) insn. ;; (define_peephole - [(set (match_operand:HI 0 "hard_reg_operand" "A") (reg:HI 1)) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + [(set (match_operand:HI 0 "hard_reg_operand" "A") (reg:HI D_REGNUM)) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] "find_regno_note (ins1, REG_DEAD, HARD_D_REGNUM)" "* { @@ -5648,10 +5682,10 @@ ;; Same as above but due to some split, there may be a noop set ;; between the two. (define_peephole - [(set (match_operand:HI 0 "hard_reg_operand" "A") (reg:HI 1)) + [(set (match_operand:HI 0 "hard_reg_operand" "A") (reg:HI D_REGNUM)) (set (match_dup 0) (match_dup 0)) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] "find_regno_note (ins1, REG_DEAD, HARD_D_REGNUM)" "* { @@ -5665,9 +5699,9 @@ ;; and we must, at least, setup X/Y with value of D. ;; (define_peephole - [(set (match_operand:HI 0 "hard_reg_operand" "A") (reg:HI 1)) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + [(set (match_operand:HI 0 "hard_reg_operand" "A") (reg:HI D_REGNUM)) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] "" "* { @@ -5685,9 +5719,9 @@ ;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. ;;; (define_peephole - [(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:HI 1) (match_dup 0))] + [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) (match_dup 0))] "find_regno_note (insn, REG_DEAD, REGNO (operands[0]))" "* { @@ -5701,9 +5735,9 @@ ;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. ;;; (define_peephole - [(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:QI 1) (match_operand:QI 1 "hard_reg_operand" "A"))] + [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:QI D_REGNUM) (match_operand:QI 1 "hard_reg_operand" "A"))] "REGNO (operands[0]) == REGNO (operands[1]) && find_regno_note (insn, REG_DEAD, REGNO (operands[0]))" "* @@ -5718,9 +5752,9 @@ ;;; need to emit anything. Otherwise, we just need a copy of D to X/Y. ;;; (define_peephole - [(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:HI 1) (match_dup 0))] + [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:HI D_REGNUM) (match_dup 0))] "" "* { @@ -5738,9 +5772,9 @@ ;;; with the xgdx. ;;; (define_peephole - [(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) - (set (match_dup 0) (reg:HI 1))]) - (set (reg:QI 1) (match_operand:QI 1 "hard_reg_operand" "A"))] + [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (set (reg:QI D_REGNUM) (match_operand:QI 1 "hard_reg_operand" "A"))] "REGNO (operands[0]) == REGNO (operands[1])" "* { @@ -5757,10 +5791,10 @@ ;;; Catch two consecutive xgdx or xgdy, emit nothing. ;;; (define_peephole - [(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) - (set (match_dup 0) (reg:HI 1))]) - (parallel [(set (reg:HI 1) (match_dup 0)) - (set (match_dup 0) (reg:HI 1))])] + [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A")) + (set (match_dup 0) (reg:HI D_REGNUM))]) + (parallel [(set (reg:HI D_REGNUM) (match_dup 0)) + (set (match_dup 0) (reg:HI D_REGNUM))])] "" "* { @@ -5834,7 +5868,7 @@ ;; (define_peephole [(set (match_operand:HI 0 "hard_reg_operand" "dA") (const_int -1)) - (set (match_dup 0) (plus:HI (match_dup 0) (reg:HI 3)))] + (set (match_dup 0) (plus:HI (match_dup 0) (reg:HI SP_REGNUM)))] "TARGET_M6811" "* {