Commit 01beec65 by Stephane Carrez Committed by Stephane Carrez

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.

From-SVN: r41802
parent 6e26f4aa
2001-05-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* 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 <Stephane.Carrez@worldnet.fr>
* 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 <Stephane.Carrez@worldnet.fr>
* 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 <Stephane.Carrez@worldnet.fr>
* 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 <Stephane.Carrez@worldnet.fr>
* 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 <Stephane.Carrez@worldnet.fr>
* 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 <Stephane.Carrez@worldnet.fr>
* 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 <obrien@FreeBSD.org> 2001-05-03 David O'Brien <obrien@FreeBSD.org>
* config.gcc(rs6000-ibm-aix|powerpc-ibm-aix): Do not include * config.gcc(rs6000-ibm-aix|powerpc-ibm-aix): Do not include
......
/* libgcc1 routines for M68HC11. /* libgcc1 routines for M68HC11 & M68HC12.
Copyright (C) 1999, 2000 Free Software Foundation, Inc. Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -47,7 +47,11 @@ NAME: .word 0; \ ...@@ -47,7 +47,11 @@ NAME: .word 0; \
/* Pseudo hard registers used by gcc. /* Pseudo hard registers used by gcc.
They must be located in page0. They must be located in page0.
They will normally appear at the end of .page0 section. */ They will normally appear at the end of .page0 section. */
#ifdef mc68hc12
.sect .bss
#else
.sect .page0 .sect .page0
#endif
.globl _.tmp,_.frame .globl _.tmp,_.frame
.globl _.z,_.xy .globl _.z,_.xy
REG(_.tmp) REG(_.tmp)
...@@ -61,7 +65,11 @@ REG(_.frame) ...@@ -61,7 +65,11 @@ REG(_.frame)
/* Pseudo hard registers used by gcc. /* Pseudo hard registers used by gcc.
They must be located in page0. They must be located in page0.
They will normally appear at the end of .page0 section. */ They will normally appear at the end of .page0 section. */
#ifdef mc68hc12
.sect .bss
#else
.sect .page0 .sect .page0
#endif
.globl _.d1,_.d2,_.d3,_.d4,_.d5,_.d6 .globl _.d1,_.d2,_.d3,_.d4,_.d5,_.d6
.globl _.d7,_.d8 .globl _.d7,_.d8
REG(_.d1) REG(_.d1)
...@@ -97,7 +105,11 @@ REG(_.d16) ...@@ -97,7 +105,11 @@ REG(_.d16)
/* Pseudo hard registers used by gcc. /* Pseudo hard registers used by gcc.
They must be located in page0. They must be located in page0.
They will normally appear at the end of .page0 section. */ They will normally appear at the end of .page0 section. */
#ifdef mc68hc12
.sect .bss
#else
.sect .page0 .sect .page0
#endif
.globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22 .globl _.d17,_.d18,_.d19,_.d20,_.d21,_.d22
.globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28 .globl _.d23,_.d24,_.d25,_.d26,_.d27,_.d28
.globl _.d29,_.d30,_.d31,_.d32 .globl _.d29,_.d30,_.d31,_.d32
...@@ -157,8 +169,12 @@ fatal: ...@@ -157,8 +169,12 @@ fatal:
.globl abort .globl abort
abort: abort:
ldd #255 ; ldd #255 ;
#ifdef mc68hc12
trap #0x30
#else
.byte 0xCD ; Generate an illegal instruction trap .byte 0xCD ; Generate an illegal instruction trap
.byte 0x03 ; The simulator catches this and stops. .byte 0x03 ; The simulator catches this and stops.
#endif
jmp _exit jmp _exit
#endif #endif
...@@ -189,6 +205,23 @@ _cleanup: ...@@ -189,6 +205,23 @@ _cleanup:
;;; ;;;
__memcpy: __memcpy:
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 xgdy
tsx tsx
ldd 4,x ldd 4,x
...@@ -214,6 +247,7 @@ End: ...@@ -214,6 +247,7 @@ End:
xgdy xgdy
rts rts
#endif #endif
#endif
#ifdef L_memset #ifdef L_memset
.sect .text .sect .text
...@@ -237,6 +271,19 @@ End: ...@@ -237,6 +271,19 @@ End:
#endif #endif
__memset: __memset:
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 xgdx
tsy tsy
ldab val,y ldab val,y
...@@ -253,6 +300,7 @@ End: ...@@ -253,6 +300,7 @@ End:
xgdx xgdx
rts rts
#endif #endif
#endif
#ifdef L_adddi3 #ifdef L_adddi3
.sect .text .sect .text
...@@ -260,29 +308,28 @@ End: ...@@ -260,29 +308,28 @@ End:
___adddi3: ___adddi3:
tsx tsx
tsy
pshb pshb
psha psha
ldd 8,x ldd 8,x
addd 16,y addd 16,x
pshb pshb
psha psha
ldd 6,x ldd 6,x
adcb 15,y adcb 15,x
adca 14,y adca 14,x
pshb pshb
psha psha
ldd 4,x ldd 4,x
adcb 13,y adcb 13,x
adca 12,y adca 12,x
pshb pshb
psha psha
ldd 2,x ldd 2,x
adcb 11,y adcb 11,x
adca 10,y adca 10,x
tsx tsx
ldy 6,x ldy 6,x
...@@ -303,29 +350,28 @@ ___adddi3: ...@@ -303,29 +350,28 @@ ___adddi3:
___subdi3: ___subdi3:
tsx tsx
tsy
pshb pshb
psha psha
ldd 8,x ldd 8,x
subd 16,y subd 16,x
pshb pshb
psha psha
ldd 6,x ldd 6,x
sbcb 15,y sbcb 15,x
sbca 14,y sbca 14,x
pshb pshb
psha psha
ldd 4,x ldd 4,x
sbcb 13,y sbcb 13,x
sbca 12,y sbca 12,x
pshb pshb
psha psha
ldd 2,x ldd 2,x
sbcb 11,y sbcb 11,x
sbca 10,y sbca 10,x
tsx tsx
ldy 6,x ldy 6,x
...@@ -681,7 +727,6 @@ A_or_B_neg: ...@@ -681,7 +727,6 @@ A_or_B_neg:
addd #1 addd #1
rts rts
AB_neg: AB_neg:
nega
negb negb
mul mul
rts rts
...@@ -699,6 +744,13 @@ AB_neg: ...@@ -699,6 +744,13 @@ AB_neg:
; b = register X ; b = register X
; ;
___mulhi3: ___mulhi3:
#ifdef mc68hc12
pshx ; Preserve X
exg x,y
emul
exg x,y
pulx
#else
stx *_.tmp stx *_.tmp
pshb pshb
ldab *_.tmp+1 ldab *_.tmp+1
...@@ -714,6 +766,7 @@ ___mulhi3: ...@@ -714,6 +766,7 @@ ___mulhi3:
pulb pulb
mul ; A.low * B.low mul ; A.low * B.low
adda *_.tmp adda *_.tmp
#endif
rts rts
#endif #endif
...@@ -750,6 +803,11 @@ ___mulhi3: ...@@ -750,6 +803,11 @@ ___mulhi3:
; <A-high> 0,x ; <A-high> 0,x
; ;
__mulhi32: __mulhi32:
#ifdef mc68hc12
ldy 2,sp
emul
exg x,y
#else
pshb pshb
psha psha
tsx tsx
...@@ -781,6 +839,7 @@ N: ...@@ -781,6 +839,7 @@ N:
Ret: Ret:
pshy pshy
pulx pulx
#endif
rts rts
#endif #endif
...@@ -823,7 +882,11 @@ __mulsi3: ...@@ -823,7 +882,11 @@ __mulsi3:
; ;
; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low) ; If A.high is 0, optimize into: (A.low * B.high) << 16 + (A.low * B.low)
; ;
#ifdef mc68hc12
cpx #0
#else
stx *_.tmp stx *_.tmp
#endif
beq A_high_zero beq A_high_zero
bsr ___mulhi3 ; A.high * B.low bsr ___mulhi3 ; A.high * B.low
; ;
...@@ -933,6 +996,10 @@ __map_data_section: ...@@ -933,6 +996,10 @@ __map_data_section:
ldx #__data_image ldx #__data_image
ldy #__data_section_start ldy #__data_section_start
Loop: Loop:
#ifdef mc68hc12
movb 1,x+,1,y+
dbne d,Loop
#else
psha psha
ldaa 0,x ldaa 0,x
staa 0,y staa 0,y
...@@ -941,6 +1008,7 @@ Loop: ...@@ -941,6 +1008,7 @@ Loop:
iny iny
subd #1 subd #1
bne Loop bne Loop
#endif
Done: Done:
#endif #endif
...@@ -955,10 +1023,15 @@ __init_bss_section: ...@@ -955,10 +1023,15 @@ __init_bss_section:
beq Done beq Done
ldx #__bss_start ldx #__bss_start
Loop: Loop:
#ifdef mc68hc12
clr 1,x+
dbne d,Loop
#else
clr 0,x clr 0,x
inx inx
subd #1 subd #1
bne Loop bne Loop
#endif
Done: Done:
#endif #endif
......
/* Prototypes for exported functions defined in m68hc11.c /* 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) Contributed by Stephane Carrez (stcarrez@worldnet.fr)
This file is part of GNU CC. This file is part of GNU CC.
...@@ -70,6 +70,7 @@ extern int m68hc11_go_if_legitimate_address PARAMS((rtx, ...@@ -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 int m68hc11_legitimize_address PARAMS((rtx*, rtx, enum machine_mode));
extern void m68hc11_notice_update_cc PARAMS((rtx, rtx)); extern void m68hc11_notice_update_cc PARAMS((rtx, rtx));
extern void m68hc11_notice_keep_cc PARAMS((rtx));
extern void m68hc11_reorg PARAMS((rtx)); extern void m68hc11_reorg PARAMS((rtx));
...@@ -137,8 +138,6 @@ extern int hard_reg_operand PARAMS((rtx, enum machine_mode)); ...@@ -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 soft_reg_operand PARAMS((rtx, enum machine_mode));
extern int reg_or_some_mem_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 #if defined TREE_CODE
extern void m68hc11_init_cumulative_args PARAMS((CUMULATIVE_ARGS*, extern void m68hc11_init_cumulative_args PARAMS((CUMULATIVE_ARGS*,
tree, tree,
......
...@@ -62,7 +62,7 @@ static int go_if_legitimate_address_internal PARAMS((rtx, enum machine_mode, ...@@ -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 int register_indirect_p PARAMS((rtx, enum machine_mode, int));
static rtx m68hc11_expand_compare PARAMS((enum rtx_code, rtx, rtx)); static rtx m68hc11_expand_compare PARAMS((enum rtx_code, rtx, rtx));
static int must_parenthesize PARAMS ((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)); static int m68hc11_auto_inc_p PARAMS ((rtx));
void create_regs_rtx PARAMS ((void)); void create_regs_rtx PARAMS ((void));
...@@ -120,6 +120,78 @@ rtx m68hc11_compare_op0; ...@@ -120,6 +120,78 @@ rtx m68hc11_compare_op0;
rtx m68hc11_compare_op1; 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 */ /* Machine specific options */
const char *m68hc11_regparm_string; const char *m68hc11_regparm_string;
...@@ -130,24 +202,11 @@ static void m68hc11_add_gc_roots PARAMS ((void)); ...@@ -130,24 +202,11 @@ static void m68hc11_add_gc_roots PARAMS ((void));
static int nb_soft_regs; 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 int
m68hc11_override_options () m68hc11_override_options ()
{ {
m68hc11_add_gc_roots (); m68hc11_add_gc_roots ();
flag_no_nonansi_builtin = 1;
memset (m68hc11_reg_valid_for_index, 0, memset (m68hc11_reg_valid_for_index, 0,
sizeof (m68hc11_reg_valid_for_index)); sizeof (m68hc11_reg_valid_for_index));
memset (m68hc11_reg_valid_for_base, 0, sizeof (m68hc11_reg_valid_for_base)); memset (m68hc11_reg_valid_for_base, 0, sizeof (m68hc11_reg_valid_for_base));
...@@ -159,7 +218,8 @@ m68hc11_override_options () ...@@ -159,7 +218,8 @@ m68hc11_override_options ()
a -m68hc11 option was specified on the command line. */ a -m68hc11 option was specified on the command line. */
if (TARGET_DEFAULT != MASK_M6811) if (TARGET_DEFAULT != MASK_M6811)
target_flags &= ~TARGET_DEFAULT; target_flags &= ~TARGET_DEFAULT;
m68hc11_cost = &m6811_cost;
m68hc11_min_offset = 0; m68hc11_min_offset = 0;
m68hc11_max_offset = 256; m68hc11_max_offset = 256;
m68hc11_index_reg_class = NO_REGS; m68hc11_index_reg_class = NO_REGS;
...@@ -176,7 +236,8 @@ m68hc11_override_options () ...@@ -176,7 +236,8 @@ m68hc11_override_options ()
/* Configure for a 68hc12 processor. */ /* Configure for a 68hc12 processor. */
if (TARGET_M6812) if (TARGET_M6812)
{ {
m68hc11_min_offset = 0; m68hc11_cost = &m6812_cost;
m68hc11_min_offset = -65536;
m68hc11_max_offset = 65536; m68hc11_max_offset = 65536;
m68hc11_index_reg_class = D_REGS; m68hc11_index_reg_class = D_REGS;
m68hc11_base_reg_class = A_OR_SP_REGS; m68hc11_base_reg_class = A_OR_SP_REGS;
...@@ -278,29 +339,6 @@ hard_regno_mode_ok (regno, mode) ...@@ -278,29 +339,6 @@ hard_regno_mode_ok (regno, mode)
} }
enum reg_class 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) preferred_reload_class (operand, class)
rtx operand; rtx operand;
enum reg_class class; enum reg_class class;
...@@ -733,13 +771,14 @@ m68hc11_emit_libcall (name, code, dmode, smode, noperands, operands) ...@@ -733,13 +771,14 @@ m68hc11_emit_libcall (name, code, dmode, smode, noperands, operands)
switch (noperands) switch (noperands)
{ {
case 2: case 2:
ret = emit_library_call_value (libcall, NULL_RTX, 1, dmode, 1, ret = emit_library_call_value (libcall, NULL_RTX, LCT_CONST,
operands[1], smode); dmode, 1, operands[1], smode);
equiv = gen_rtx (code, dmode, operands[1]); equiv = gen_rtx (code, dmode, operands[1]);
break; break;
case 3: 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], operands[1], smode, operands[2],
smode); smode);
equiv = gen_rtx (code, dmode, operands[1], operands[2]); equiv = gen_rtx (code, dmode, operands[1], operands[2]);
...@@ -2125,9 +2164,19 @@ print_operand (file, op, letter) ...@@ -2125,9 +2164,19 @@ print_operand (file, op, letter)
} }
else else
{ {
int need_parenthesize = 0;
if (letter != 'i') if (letter != 'i')
asm_fprintf (file, "%0I"); asm_fprintf (file, "%0I");
else
need_parenthesize = must_parenthesize (op);
if (need_parenthesize)
asm_fprintf (file, "(");
output_addr_const (file, op); output_addr_const (file, op);
if (need_parenthesize)
asm_fprintf (file, ")");
} }
} }
...@@ -2508,6 +2557,7 @@ m68hc11_split_move (to, from, scratch) ...@@ -2508,6 +2557,7 @@ m68hc11_split_move (to, from, scratch)
rtx low_to, low_from; rtx low_to, low_from;
rtx high_to, high_from; rtx high_to, high_from;
enum machine_mode mode; enum machine_mode mode;
int offset = 0;
mode = GET_MODE (to); mode = GET_MODE (to);
if (GET_MODE_SIZE (mode) == 8) if (GET_MODE_SIZE (mode) == 8)
...@@ -2517,6 +2567,22 @@ m68hc11_split_move (to, from, scratch) ...@@ -2517,6 +2567,22 @@ m68hc11_split_move (to, from, scratch)
else else
mode = QImode; 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); low_to = m68hc11_gen_lowpart (mode, to);
high_to = m68hc11_gen_highpart (mode, to); high_to = m68hc11_gen_highpart (mode, to);
...@@ -2531,6 +2597,11 @@ m68hc11_split_move (to, from, scratch) ...@@ -2531,6 +2597,11 @@ m68hc11_split_move (to, from, scratch)
else else
high_from = m68hc11_gen_highpart (mode, from); high_from = m68hc11_gen_highpart (mode, from);
if (offset)
{
high_from = adj_offsettable_operand (high_from, offset);
low_from = high_from;
}
if (mode == SImode) if (mode == SImode)
{ {
m68hc11_split_move (low_to, low_from, scratch); m68hc11_split_move (low_to, low_from, scratch);
...@@ -2823,6 +2894,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2823,6 +2894,7 @@ m68hc11_gen_movhi (insn, operands)
{ {
if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1])) if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1]))
{ {
cc_status = cc_prev_status;
switch (REGNO (operands[1])) switch (REGNO (operands[1]))
{ {
case HARD_X_REGNUM: case HARD_X_REGNUM:
...@@ -2837,6 +2909,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2837,6 +2909,7 @@ m68hc11_gen_movhi (insn, operands)
} }
if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0])) if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0]))
{ {
cc_status = cc_prev_status;
switch (REGNO (operands[0])) switch (REGNO (operands[0]))
{ {
case HARD_X_REGNUM: case HARD_X_REGNUM:
...@@ -2851,6 +2924,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2851,6 +2924,7 @@ m68hc11_gen_movhi (insn, operands)
} }
if (H_REG_P (operands[0]) && H_REG_P (operands[1])) 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); output_asm_insn ("tfr\t%1,%0", operands);
} }
else if (H_REG_P (operands[0])) else if (H_REG_P (operands[0]))
...@@ -2892,6 +2966,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2892,6 +2966,7 @@ m68hc11_gen_movhi (insn, operands)
else else
{ {
/* !!!! SCz wrong here. */ /* !!!! SCz wrong here. */
fatal_insn ("Move insn not handled", insn);
} }
} }
else else
...@@ -2903,6 +2978,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2903,6 +2978,7 @@ m68hc11_gen_movhi (insn, operands)
} }
else else
{ {
m68hc11_notice_keep_cc (operands[0]);
output_asm_insn ("movw\t%1,%0", operands); output_asm_insn ("movw\t%1,%0", operands);
} }
} }
...@@ -2912,6 +2988,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2912,6 +2988,7 @@ m68hc11_gen_movhi (insn, operands)
if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0])) if (IS_STACK_POP (operands[1]) && H_REG_P (operands[0]))
{ {
cc_status = cc_prev_status;
switch (REGNO (operands[0])) switch (REGNO (operands[0]))
{ {
case HARD_X_REGNUM: case HARD_X_REGNUM:
...@@ -2947,7 +3024,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -2947,7 +3024,7 @@ m68hc11_gen_movhi (insn, operands)
} }
else else
{ {
cc_status = cc_prev_status; m68hc11_notice_keep_cc (operands[0]);
output_asm_insn ("pshx\n\tpula\n\tpulb", operands); output_asm_insn ("pshx\n\tpula\n\tpulb", operands);
} }
} }
...@@ -3002,7 +3079,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -3002,7 +3079,7 @@ m68hc11_gen_movhi (insn, operands)
} }
else else
{ {
cc_status = cc_prev_status; m68hc11_notice_keep_cc (operands[0]);
output_asm_insn ("pshb", operands); output_asm_insn ("pshb", operands);
output_asm_insn ("psha", operands); output_asm_insn ("psha", operands);
output_asm_insn ("pulx", operands); output_asm_insn ("pulx", operands);
...@@ -3058,7 +3135,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -3058,7 +3135,7 @@ m68hc11_gen_movhi (insn, operands)
case HARD_SP_REGNUM: case HARD_SP_REGNUM:
if (D_REG_P (operands[1])) 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 ("xgdx", operands);
output_asm_insn ("txs", operands); output_asm_insn ("txs", operands);
output_asm_insn ("xgdx", operands); output_asm_insn ("xgdx", operands);
...@@ -3099,6 +3176,7 @@ m68hc11_gen_movhi (insn, operands) ...@@ -3099,6 +3176,7 @@ m68hc11_gen_movhi (insn, operands)
if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1])) if (IS_STACK_PUSH (operands[0]) && H_REG_P (operands[1]))
{ {
cc_status = cc_prev_status;
switch (REGNO (operands[1])) switch (REGNO (operands[1]))
{ {
case HARD_X_REGNUM: case HARD_X_REGNUM:
...@@ -3182,25 +3260,26 @@ m68hc11_gen_movqi (insn, operands) ...@@ -3182,25 +3260,26 @@ m68hc11_gen_movqi (insn, operands)
if (H_REG_P (operands[0]) && H_REG_P (operands[1])) 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); output_asm_insn ("tfr\t%1,%0", operands);
} }
else if (H_REG_P (operands[0])) else if (H_REG_P (operands[0]))
{ {
if (Q_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])) else if (D_REG_P (operands[0]))
output_asm_insn ("ldab\t%1", operands); output_asm_insn ("ldab\t%b1", operands);
else else
output_asm_insn ("ld%0\t%1", operands); goto m6811_move;
} }
else if (H_REG_P (operands[1])) else if (H_REG_P (operands[1]))
{ {
if (Q_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])) else if (D_REG_P (operands[1]))
output_asm_insn ("staa\t%0", operands); output_asm_insn ("stab\t%b0", operands);
else else
output_asm_insn ("st%1\t%0", operands); goto m6811_move;
} }
else else
{ {
...@@ -3227,6 +3306,7 @@ m68hc11_gen_movqi (insn, operands) ...@@ -3227,6 +3306,7 @@ m68hc11_gen_movqi (insn, operands)
else else
{ {
/* !!!! SCz wrong here. */ /* !!!! SCz wrong here. */
fatal_insn ("Move insn not handled", insn);
} }
} }
else else
...@@ -3237,13 +3317,15 @@ m68hc11_gen_movqi (insn, operands) ...@@ -3237,13 +3317,15 @@ m68hc11_gen_movqi (insn, operands)
} }
else else
{ {
output_asm_insn ("movb\t%1,%0", operands); m68hc11_notice_keep_cc (operands[0]);
output_asm_insn ("movb\t%b1,%b0", operands);
} }
} }
} }
return; return;
} }
m6811_move:
if (H_REG_P (operands[0])) if (H_REG_P (operands[0]))
{ {
switch (REGNO (operands[0])) switch (REGNO (operands[0]))
...@@ -3618,6 +3700,24 @@ m68hc11_notice_update_cc (exp, insn) ...@@ -3618,6 +3700,24 @@ m68hc11_notice_update_cc (exp, insn)
&& reg_overlap_mentioned_p (cc_status.value1, cc_status.value2)) && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
cc_status.value2 = 0; 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. */ /* Machine Specific Reorg. */
...@@ -3911,7 +4011,7 @@ m68hc11_check_z_replacement (insn, info) ...@@ -3911,7 +4011,7 @@ m68hc11_check_z_replacement (insn, info)
} }
info->x_used = 1; info->x_used = 1;
if (z_dies_here && !reg_mentioned_p (src, ix_reg) 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->need_save_z = 0;
info->z_died = 1; info->z_died = 1;
...@@ -3982,7 +4082,7 @@ m68hc11_check_z_replacement (insn, info) ...@@ -3982,7 +4082,7 @@ m68hc11_check_z_replacement (insn, info)
} }
info->y_used = 1; info->y_used = 1;
if (z_dies_here && !reg_mentioned_p (src, iy_reg) 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->need_save_z = 0;
info->z_died = 1; info->z_died = 1;
...@@ -4356,6 +4456,8 @@ m68hc11_z_replacement (insn) ...@@ -4356,6 +4456,8 @@ m68hc11_z_replacement (insn)
&& INTVAL (src) == 0) && INTVAL (src) == 0)
{ {
XEXP (body, 0) = gen_rtx (REG, GET_MODE (dst), SOFT_Z_REGNUM); XEXP (body, 0) = gen_rtx (REG, GET_MODE (dst), SOFT_Z_REGNUM);
/* Force it to be re-recognized. */
INSN_CODE (insn) = -1;
return; return;
} }
} }
...@@ -4577,6 +4679,7 @@ m68hc11_reorg (first) ...@@ -4577,6 +4679,7 @@ m68hc11_reorg (first)
rtx first; rtx first;
{ {
int split_done = 0; int split_done = 0;
rtx insn;
z_replacement_completed = 0; z_replacement_completed = 0;
z_reg = gen_rtx (REG, HImode, HARD_Z_REGNUM); z_reg = gen_rtx (REG, HImode, HARD_Z_REGNUM);
...@@ -4602,6 +4705,28 @@ m68hc11_reorg (first) ...@@ -4602,6 +4705,28 @@ m68hc11_reorg (first)
description to use the best assembly directives. */ description to use the best assembly directives. */
if (optimize) 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 = &REG_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); find_basic_blocks (first, max_reg_num (), 0);
life_analysis (first, 0, PROP_REG_INFO | PROP_DEATH_NOTES); life_analysis (first, 0, PROP_REG_INFO | PROP_DEATH_NOTES);
} }
...@@ -4651,8 +4776,6 @@ m68hc11_reorg (first) ...@@ -4651,8 +4776,6 @@ m68hc11_reorg (first)
/* Cost functions. */ /* Cost functions. */
#define COSTS_N_INSNS(N) ((N) * 4 - 2)
/* Cost of moving memory. */ /* Cost of moving memory. */
int int
m68hc11_memory_move_cost (mode, class, in) m68hc11_memory_move_cost (mode, class, in)
...@@ -4783,10 +4906,43 @@ m68hc11_address_cost (addr) ...@@ -4783,10 +4906,43 @@ m68hc11_address_cost (addr)
return cost; 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 int
m68hc11_rtx_costs (x, code, outer_code) m68hc11_rtx_costs (x, code, outer_code)
rtx x; 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); enum machine_mode mode = GET_MODE (x);
int extra_cost = 0; int extra_cost = 0;
...@@ -4794,9 +4950,6 @@ m68hc11_rtx_costs (x, code, outer_code) ...@@ -4794,9 +4950,6 @@ m68hc11_rtx_costs (x, code, outer_code)
switch (code) switch (code)
{ {
case MEM:
return m68hc11_address_cost (XEXP (x, 0)) + 4;
case ROTATE: case ROTATE:
case ROTATERT: case ROTATERT:
case ASHIFT: case ASHIFT:
...@@ -4804,82 +4957,91 @@ m68hc11_rtx_costs (x, code, outer_code) ...@@ -4804,82 +4957,91 @@ m68hc11_rtx_costs (x, code, outer_code)
case ASHIFTRT: case ASHIFTRT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT) if (GET_CODE (XEXP (x, 1)) == CONST_INT)
{ {
int val = INTVAL (XEXP (x, 1)); return m68hc11_shift_cost (mode, XEXP (x, 0), 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);
} }
total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code);
total += m68hc11_cost->shift_var;
return total; return total;
case MINUS:
case PLUS:
case AND: case AND:
case XOR: case XOR:
case IOR: 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) /* Logical instructions are byte instructions only. */
+ rtx_cost (XEXP (x, 1), outer_code); total *= GET_MODE_SIZE (mode);
if (GET_MODE_SIZE (mode) <= 2) return total;
{
total += COSTS_N_INSNS (2); case MINUS:
} case PLUS:
else 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; return total;
case UDIV:
case DIV: case DIV:
case MOD: case MOD:
if (mode == QImode || mode == HImode) total = rtx_cost (XEXP (x, 0), code) + rtx_cost (XEXP (x, 1), code);
{ switch (mode)
return 30; {
} case QImode:
else if (mode == SImode) total += m68hc11_cost->divQI;
{ break;
return 100;
} case HImode:
else total += m68hc11_cost->divHI;
{ break;
return 150;
} case SImode:
default:
total += m68hc11_cost->divSI;
break;
}
return total;
case MULT: case MULT:
if (mode == QImode) /* mul instruction produces 16-bit result. */
{ if (mode == HImode && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
return TARGET_OP_TIME ? 10 : 2; && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
} return m68hc11_cost->multQI
if (mode == HImode) + rtx_cost (XEXP (XEXP (x, 0), 0), code)
{ + rtx_cost (XEXP (XEXP (x, 1), 0), code);
return TARGET_OP_TIME ? 30 : 4;
} /* emul instruction produces 32-bit result for 68HC12. */
if (mode == SImode) if (TARGET_M6812 && mode == SImode
{ && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
return TARGET_OP_TIME ? 100 : 20; && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
} return m68hc11_cost->multHI
return 150; + 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 NEG:
case SIGN_EXTEND: case SIGN_EXTEND:
...@@ -4890,20 +5052,20 @@ m68hc11_rtx_costs (x, code, outer_code) ...@@ -4890,20 +5052,20 @@ m68hc11_rtx_costs (x, code, outer_code)
case COMPARE: case COMPARE:
case ABS: case ABS:
case ZERO_EXTEND: case ZERO_EXTEND:
total = rtx_cost (XEXP (x, 0), outer_code); total = extra_cost + rtx_cost (XEXP (x, 0), code);
if (mode == QImode) if (mode == QImode)
{ {
return total + extra_cost + COSTS_N_INSNS (1); return total + COSTS_N_INSNS (1);
} }
if (mode == HImode) if (mode == HImode)
{ {
return total + extra_cost + COSTS_N_INSNS (2); return total + COSTS_N_INSNS (2);
} }
if (mode == SImode) 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: case IF_THEN_ELSE:
if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC) if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
......
...@@ -207,6 +207,25 @@ extern const char *m68hc11_soft_reg_count; ...@@ -207,6 +207,25 @@ extern const char *m68hc11_soft_reg_count;
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */ `-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
#define OVERRIDE_OPTIONS m68hc11_override_options (); #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 */ /* target machine storage layout */
...@@ -769,9 +788,6 @@ extern enum reg_class m68hc11_tmp_regs_class; ...@@ -769,9 +788,6 @@ extern enum reg_class m68hc11_tmp_regs_class;
#define PREFERRED_RELOAD_CLASS(X,CLASS) preferred_reload_class(X,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 #define SMALL_REGISTER_CLASSES 1
/* A C expression whose value is nonzero if pseudos that have been /* 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]; ...@@ -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 /* 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 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, the code is computed here, return it with a return statement. Otherwise,
break from the switch. */ break from the switch.
#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
case CONST_INT: \ Constants are cheap. Moving them in registers must be avoided
if (RTX == const0_rtx) return 0; \ because most instructions do not handle two register operands. */
case CONST: \ #define CONST_COSTS(RTX,CODE,OUTER_CODE) \
return 0; \ case CONST_INT: \
case LABEL_REF: \ /* Logical and arithmetic operations with a constant */ \
case SYMBOL_REF: \ /* operand are better because they are not supported */ \
return 1; \ /* with two registers. */ \
case CONST_DOUBLE: \ /* '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; return 0;
#define DEFAULT_RTX_COSTS(X,CODE,OUTER_CODE) \ #define RTX_COSTS(X,CODE,OUTER_CODE) \
return m68hc11_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 /* An expression giving the cost of an addressing mode that contains
ADDRESS. If not defined, the cost is computed from the ADDRESS ADDRESS. If not defined, the cost is computed from the ADDRESS
......
...@@ -115,6 +115,24 @@ ...@@ -115,6 +115,24 @@
;; Such split pattern must also be valid when z_replacement_completed == 2 ;; 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}. ;; 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 ;;- Test
...@@ -156,7 +174,7 @@ ...@@ -156,7 +174,7 @@
"" ""
"* "*
{ {
if (D_REG_P (operands[0])) if (D_REG_P (operands[0]) && !TARGET_M6812)
return \"std\\t%t0\"; return \"std\\t%t0\";
else else
return \"cp%0\\t#0\"; return \"cp%0\\t#0\";
...@@ -222,10 +240,10 @@ ...@@ -222,10 +240,10 @@
(use (match_operand:HI 1 "hard_reg_operand" "dxy")) (use (match_operand:HI 1 "hard_reg_operand" "dxy"))
(use (reg:HI 11))] (use (reg:HI 11))]
"z_replacement_completed == 2" "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 (match_dup 1) (match_dup 2))
(set (cc0) (match_dup 0)) (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);") "operands[2] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);")
...@@ -313,10 +331,10 @@ ...@@ -313,10 +331,10 @@
(use (match_operand:HI 2 "hard_reg_operand" "dxy")) (use (match_operand:HI 2 "hard_reg_operand" "dxy"))
(use (reg:HI 11))] (use (reg:HI 11))]
"z_replacement_completed == 2" "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 (match_dup 2) (match_dup 3))
(set (cc0) (compare (match_dup 0) (match_dup 1))) (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);") "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);")
;; ;;
...@@ -330,12 +348,12 @@ ...@@ -330,12 +348,12 @@
(compare (match_operand:QI 0 "hard_addr_reg_operand" "xy") (compare (match_operand:QI 0 "hard_addr_reg_operand" "xy")
(match_operand:QI 1 "cmp_operand" "uimA")))] (match_operand:QI 1 "cmp_operand" "uimA")))]
"z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode" "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode"
[(parallel [(set (reg:HI 1) (match_dup 3)) [(parallel [(set (reg:HI D_REGNUM) (match_dup 3))
(set (match_dup 3) (reg:HI 1))]) (set (match_dup 3) (reg:HI D_REGNUM))])
(set (cc0) (set (cc0)
(compare (reg:QI 1) (match_dup 1))) (compare (reg:QI D_REGNUM) (match_dup 1)))
(parallel [(set (reg:HI 1) (match_dup 3)) (parallel [(set (reg:HI D_REGNUM) (match_dup 3))
(set (match_dup 3) (reg:HI 1))])] (set (match_dup 3) (reg:HI D_REGNUM))])]
"operands[3] = gen_rtx (REG, HImode, REGNO (operands[0]));") "operands[3] = gen_rtx (REG, HImode, REGNO (operands[0]));")
(define_split (define_split
...@@ -392,10 +410,10 @@ ...@@ -392,10 +410,10 @@
(use (match_operand:HI 2 "hard_reg_operand" "dxy")) (use (match_operand:HI 2 "hard_reg_operand" "dxy"))
(use (reg:HI 11))] (use (reg:HI 11))]
"z_replacement_completed == 2" "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 (match_dup 2) (match_dup 3))
(set (cc0) (compare (match_dup 0) (match_dup 1))) (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);") "operands[3] = gen_rtx (REG, HImode, SOFT_Z_REGNUM);")
(define_expand "cmpdf" (define_expand "cmpdf"
...@@ -703,11 +721,11 @@ ...@@ -703,11 +721,11 @@
"z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode "z_replacement_completed == 2 && GET_MODE (operands[0]) == QImode
&& !reg_mentioned_p (operands[0], operands[1]) && !reg_mentioned_p (operands[0], operands[1])
&& !D_REG_P (operands[1])" && !D_REG_P (operands[1])"
[(parallel [(set (reg:HI 1) (match_dup 2)) [(parallel [(set (reg:HI D_REGNUM) (match_dup 2))
(set (match_dup 2) (reg:HI 1))]) (set (match_dup 2) (reg:HI D_REGNUM))])
(set (reg:QI 1) (match_dup 1)) (set (reg:QI D_REGNUM) (match_dup 1))
(parallel [(set (reg:HI 1) (match_dup 2)) (parallel [(set (reg:HI D_REGNUM) (match_dup 2))
(set (match_dup 2) (reg:HI 1))])] (set (match_dup 2) (reg:HI D_REGNUM))])]
"operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));") "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));")
;; ;;
...@@ -719,11 +737,11 @@ ...@@ -719,11 +737,11 @@
"z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode "z_replacement_completed == 2 && GET_MODE (operands[1]) == QImode
&& !reg_mentioned_p (operands[1], operands[0]) && !reg_mentioned_p (operands[1], operands[0])
&& !D_REG_P (operands[0])" && !D_REG_P (operands[0])"
[(parallel [(set (reg:HI 1) (match_dup 2)) [(parallel [(set (reg:HI D_REGNUM) (match_dup 2))
(set (match_dup 2) (reg:HI 1))]) (set (match_dup 2) (reg:HI D_REGNUM))])
(set (match_dup 0) (reg:QI 1)) (set (match_dup 0) (reg:QI D_REGNUM))
(parallel [(set (reg:HI 1) (match_dup 2)) (parallel [(set (reg:HI D_REGNUM) (match_dup 2))
(set (match_dup 2) (reg:HI 1))])] (set (match_dup 2) (reg:HI D_REGNUM))])]
"operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));") "operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));")
(define_insn "*movqi2_push" (define_insn "*movqi2_push"
...@@ -1048,15 +1066,11 @@ ...@@ -1048,15 +1066,11 @@
[(set (match_operand:SI 0 "non_push_operand" "=mu") [(set (match_operand:SI 0 "non_push_operand" "=mu")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dxy")))] (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "dxy")))]
"reload_completed && !X_REG_P (operands[0])" "reload_completed && !X_REG_P (operands[0])"
[(set (match_dup 2) (match_dup 3)) [(set (match_dup 2) (zero_extend:HI (match_dup 1)))
(set (match_dup 4) (const_int 0)) (set (match_dup 3) (const_int 0))]
(set (match_dup 5) (const_int 0))]
" "
operands[2] = m68hc11_gen_lowpart (HImode, operands[0]); operands[2] = m68hc11_gen_lowpart (HImode, operands[0]);
operands[3] = gen_rtx (REG, HImode, REGNO (operands[1])); operands[3] = m68hc11_gen_highpart (HImode, operands[0]);")
operands[4] = m68hc11_gen_lowpart (HImode, operands[0]);
operands[4] = m68hc11_gen_highpart (QImode, operands[4]);
operands[5] = m68hc11_gen_highpart (HImode, operands[0]);")
(define_split (define_split
[(set (match_operand:SI 0 "hard_reg_operand" "=D") [(set (match_operand:SI 0 "hard_reg_operand" "=D")
...@@ -1320,8 +1334,8 @@ ...@@ -1320,8 +1334,8 @@
[(set (match_operand:SI 0 "register_operand" "=D") [(set (match_operand:SI 0 "register_operand" "=D")
(sign_extend:SI (match_operand:HI 1 "register_operand" "A")))] (sign_extend:SI (match_operand:HI 1 "register_operand" "A")))]
"reload_completed && (Y_REG_P (operands[1]) || Z_REG_P (operands[1]))" "reload_completed && (Y_REG_P (operands[1]) || Z_REG_P (operands[1]))"
[(set (reg:HI 1) (match_dup 1)) [(set (reg:HI D_REGNUM) (match_dup 1))
(set (match_dup 0) (sign_extend:SI (reg:HI 1)))] (set (match_dup 0) (sign_extend:SI (reg:HI D_REGNUM)))]
"") "")
(define_insn "extendhisi2" (define_insn "extendhisi2"
...@@ -1409,13 +1423,13 @@ ...@@ -1409,13 +1423,13 @@
(match_dup 0))) (match_dup 0)))
(clobber (match_scratch:HI 1 "=X"))] (clobber (match_scratch:HI 1 "=X"))]
"reload_completed && z_replacement_completed == 2" "reload_completed && z_replacement_completed == 2"
[(set (reg:HI 1) (ashift:HI (reg:HI 1) (const_int 1))) [(set (reg:HI D_REGNUM) (ashift:HI (reg:HI D_REGNUM) (const_int 1)))
(parallel [(set (reg:HI 1) (reg:HI 0)) (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI 0) (reg:HI 1))]) (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])
(set (reg:QI 6) (rotate:QI (reg:QI 6) (reg:QI 7))) (set (reg:QI B_REGNUM) (rotate:QI (reg:QI B_REGNUM) (reg:QI CC_REGNUM)))
(set (reg:QI 5) (rotate:QI (reg:QI 5) (reg:QI 7))) (set (reg:QI A_REGNUM) (rotate:QI (reg:QI A_REGNUM) (reg:QI CC_REGNUM)))
(parallel [(set (reg:HI 1) (reg:HI 0)) (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI 0) (reg:HI 1))])] (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])]
"") "")
...@@ -1472,9 +1486,9 @@ ...@@ -1472,9 +1486,9 @@
(match_operand:SI 2 "memory_operand" "m,m"))) (match_operand:SI 2 "memory_operand" "m,m")))
(clobber (match_scratch:HI 3 "=X,X"))] (clobber (match_scratch:HI 3 "=X,X"))]
"reload_completed" "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) (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))])] (clobber (match_dup 3))])]
"") "")
...@@ -1658,7 +1672,7 @@ ...@@ -1658,7 +1672,7 @@
(clobber (match_scratch:HI 3 "=X"))] (clobber (match_scratch:HI 3 "=X"))]
"reload_completed && z_replacement_completed == 2 "reload_completed && z_replacement_completed == 2
&& ((INTVAL (operands[2]) & 0x0FFFF) == 0)" && ((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]);") "operands[3] = m68hc11_gen_highpart (HImode, operands[2]);")
(define_split (define_split
...@@ -1669,13 +1683,13 @@ ...@@ -1669,13 +1683,13 @@
"reload_completed && z_replacement_completed == 2 "reload_completed && z_replacement_completed == 2
&& (GET_CODE (operands[2]) != CONST_INT || && (GET_CODE (operands[2]) != CONST_INT ||
(!(INTVAL (operands[2]) >= -65536 && INTVAL (operands[2]) <= 65535)))" (!(INTVAL (operands[2]) >= -65536 && INTVAL (operands[2]) <= 65535)))"
[(set (reg:HI 1) (plus:HI (reg:HI 1) (match_dup 3))) [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3)))
(parallel [(set (reg:HI 1) (reg:HI 0)) (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI 0) (reg:HI 1))]) (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])
(set (reg:QI 6) (plus:QI (plus:QI (reg:QI 7) (reg:QI 6)) (match_dup 4))) (set (reg:QI B_REGNUM) (plus:QI (plus:QI (reg:QI CC_REGNUM) (reg:QI B_REGNUM)) (match_dup 4)))
(set (reg:QI 5) (plus:QI (plus:QI (reg:QI 7) (reg:QI 5)) (match_dup 5))) (set (reg:QI A_REGNUM) (plus:QI (plus:QI (reg:QI CC_REGNUM) (reg:QI A_REGNUM)) (match_dup 5)))
(parallel [(set (reg:HI 1) (reg:HI 0)) (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI 0) (reg:HI 1))])] (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])]
"operands[3] = m68hc11_gen_lowpart (HImode, operands[2]); "operands[3] = m68hc11_gen_lowpart (HImode, operands[2]);
operands[4] = m68hc11_gen_highpart (HImode, operands[2]); operands[4] = m68hc11_gen_highpart (HImode, operands[2]);
operands[5] = m68hc11_gen_highpart (QImode, operands[4]); operands[5] = m68hc11_gen_highpart (QImode, operands[4]);
...@@ -1689,7 +1703,7 @@ ...@@ -1689,7 +1703,7 @@
[(set (match_operand:HI 0 "register_operand" "=x") [(set (match_operand:HI 0 "register_operand" "=x")
(plus:HI (plus:HI (match_operand:HI 1 "register_operand" "0") (plus:HI (plus:HI (match_operand:HI 1 "register_operand" "0")
(const_int 0)) (const_int 0))
(reg:HI 7)))] (reg:HI CC_REGNUM)))]
"" ""
"* "*
{ {
...@@ -1746,25 +1760,39 @@ ...@@ -1746,25 +1760,39 @@
"") "")
(define_insn "*addhi3_68hc12" (define_insn "*addhi3_68hc12"
[(set (match_operand:HI 0 "register_operand" "=d,A*w,A*w") [(set (match_operand:HI 0 "register_operand" "=*d,A*w,A*w,A")
(plus:HI (match_operand:HI 1 "register_operand" "%0,0,Aw") (plus:HI (match_operand:HI 1 "register_operand" "%0,0,Aw,0")
(match_operand:HI 2 "general_operand" "imA*wu,id,id")))] (match_operand:HI 2 "general_operand" "imA*wu,id,id,!muA")))]
"TARGET_M6812" "TARGET_M6812"
"* "*
{ {
int val; int val;
const char* insn_code; 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 (D_REG_P (operands[0]))
{ {
if (X_REG_P (operands[2])) if (X_REG_P (operands[2]))
{ {
m68hc11_notice_keep_cc (operands[0]);
output_asm_insn (\"xgdx\", operands); output_asm_insn (\"xgdx\", operands);
output_asm_insn (\"leax\\td,%2\", operands); output_asm_insn (\"leax\\td,%2\", operands);
return \"xgdx\"; return \"xgdx\";
} }
else if (Y_REG_P (operands[2])) else if (Y_REG_P (operands[2]))
{ {
m68hc11_notice_keep_cc (operands[0]);
output_asm_insn (\"xgdy\", operands); output_asm_insn (\"xgdy\", operands);
output_asm_insn (\"leay\\td,%2\", operands); output_asm_insn (\"leay\\td,%2\", operands);
return \"xgdy\"; return \"xgdy\";
...@@ -1784,7 +1812,7 @@ ...@@ -1784,7 +1812,7 @@
if (val != -1 || val != 1 || !rtx_equal_p (operands[0], operands[1])) 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])) switch (REGNO (operands[0]))
{ {
case HARD_X_REGNUM: case HARD_X_REGNUM:
...@@ -1922,9 +1950,9 @@ ...@@ -1922,9 +1950,9 @@
"") "")
(define_insn "*addhi3" (define_insn "*addhi3"
[(set (match_operand:HI 0 "hard_reg_operand" "=A,d,!A,d*A,!d,!w") [(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,0") (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,i")))] (match_operand:HI 2 "general_operand" "N,i,I,umi*A*d,!*d*w")))]
"TARGET_M6811" "TARGET_M6811"
"* "*
{ {
...@@ -2110,7 +2138,7 @@ ...@@ -2110,7 +2138,7 @@
;; ;;
(define_insn "*adcq" (define_insn "*adcq"
[(set (match_operand:QI 0 "register_operand" "=q") [(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 1 "register_operand" "%0"))
(match_operand:QI 2 "general_operand" "ium")))] (match_operand:QI 2 "general_operand" "ium")))]
"" ""
...@@ -2201,13 +2229,13 @@ ...@@ -2201,13 +2229,13 @@
(clobber (match_scratch:HI 3 "=X"))] (clobber (match_scratch:HI 3 "=X"))]
"reload_completed && z_replacement_completed == 2 "reload_completed && z_replacement_completed == 2
&& X_REG_P (operands[1])" && X_REG_P (operands[1])"
[(set (reg:HI 1) (minus:HI (reg:HI 1) (match_dup 3))) [(set (reg:HI D_REGNUM) (minus:HI (reg:HI D_REGNUM) (match_dup 3)))
(parallel [(set (reg:HI 0) (reg:HI 1)) (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
(set (reg:HI 1) (reg:HI 0))]) (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])
(set (reg:QI 6) (minus:QI (minus:QI (reg:QI 7) (reg:QI 6)) (match_dup 4))) (set (reg:QI B_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI B_REGNUM)) (match_dup 4)))
(set (reg:QI 5) (minus:QI (minus:QI (reg:QI 7) (reg:QI 5)) (match_dup 5))) (set (reg:QI A_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI A_REGNUM)) (match_dup 5)))
(parallel [(set (reg:HI 0) (reg:HI 1)) (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
(set (reg:HI 1) (reg:HI 0))])] (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])]
"operands[3] = m68hc11_gen_lowpart (HImode, operands[2]); "operands[3] = m68hc11_gen_lowpart (HImode, operands[2]);
operands[4] = m68hc11_gen_highpart (HImode, operands[2]); operands[4] = m68hc11_gen_highpart (HImode, operands[2]);
operands[5] = m68hc11_gen_highpart (QImode, operands[4]); operands[5] = m68hc11_gen_highpart (QImode, operands[4]);
...@@ -2220,13 +2248,13 @@ ...@@ -2220,13 +2248,13 @@
(clobber (match_scratch:HI 3 "=X"))] (clobber (match_scratch:HI 3 "=X"))]
"reload_completed && z_replacement_completed == 2 "reload_completed && z_replacement_completed == 2
&& X_REG_P (operands[2])" && X_REG_P (operands[2])"
[(set (reg:HI 1) (minus:HI (reg:HI 1) (match_dup 3))) [(set (reg:HI D_REGNUM) (minus:HI (reg:HI D_REGNUM) (match_dup 3)))
(parallel [(set (reg:HI 0) (reg:HI 1)) (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
(set (reg:HI 1) (reg:HI 0))]) (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])
(set (reg:QI 6) (minus:QI (minus:QI (reg:QI 7) (reg:QI 6)) (match_dup 4))) (set (reg:QI B_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI B_REGNUM)) (match_dup 4)))
(set (reg:QI 5) (minus:QI (minus:QI (reg:QI 7) (reg:QI 5)) (match_dup 5))) (set (reg:QI A_REGNUM) (minus:QI (minus:QI (reg:QI CC_REGNUM) (reg:QI A_REGNUM)) (match_dup 5)))
(parallel [(set (reg:HI 0) (reg:HI 1)) (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
(set (reg:HI 1) (reg:HI 0))]) (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])
(set (reg:SI 0) (neg:SI (reg:SI 0)))] (set (reg:SI 0) (neg:SI (reg:SI 0)))]
"operands[3] = m68hc11_gen_lowpart (HImode, operands[1]); "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]);
operands[4] = m68hc11_gen_highpart (HImode, operands[1]); operands[4] = m68hc11_gen_highpart (HImode, operands[1]);
...@@ -2365,7 +2393,7 @@ ...@@ -2365,7 +2393,7 @@
;; ;;
(define_insn "*subcq" (define_insn "*subcq"
[(set (match_operand:QI 0 "register_operand" "=q") [(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 1 "register_operand" "0"))
(match_operand:QI 2 "general_operand" "ium")))] (match_operand:QI 2 "general_operand" "ium")))]
"" ""
...@@ -2927,10 +2955,10 @@ ...@@ -2927,10 +2955,10 @@
(match_operand:QI 1 "general_operand" "dxy,imu")) (match_operand:QI 1 "general_operand" "dxy,imu"))
(match_operand:SI 2 "general_operand" "imuD,imuD")]))] (match_operand:SI 2 "general_operand" "imuD,imuD")]))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (reg:QI 5) (match_dup 4)) [(set (reg:QI A_REGNUM) (match_dup 4))
(set (reg:QI 1) (match_dup 7)) (set (reg:QI D_REGNUM) (match_dup 7))
(set (reg:QI 6) (match_op_dup 3 [(reg:QI 6) (match_dup 5)])) (set (reg:QI B_REGNUM) (match_op_dup 3 [(reg:QI B_REGNUM) (match_dup 5)]))
(set (reg:HI 0) (match_dup 6))] (set (reg:HI X_REGNUM) (match_dup 6))]
"PUT_MODE (operands[3], QImode); "PUT_MODE (operands[3], QImode);
if (X_REG_P (operands[2])) if (X_REG_P (operands[2]))
{ {
...@@ -2957,9 +2985,9 @@ ...@@ -2957,9 +2985,9 @@
(match_operand:HI 1 "general_operand" "dA,imu")) (match_operand:HI 1 "general_operand" "dA,imu"))
(match_operand:SI 2 "general_operand" "imuD,imuD")]))] (match_operand:SI 2 "general_operand" "imuD,imuD")]))]
"reload_completed" "reload_completed"
[(set (reg:HI 1) (match_dup 4)) [(set (reg:HI D_REGNUM) (match_dup 4))
(set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 5)])) (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)]))
(set (reg:HI 0) (match_dup 6))] (set (reg:HI X_REGNUM) (match_dup 6))]
"PUT_MODE (operands[3], HImode); "PUT_MODE (operands[3], HImode);
if (X_REG_P (operands[2])) if (X_REG_P (operands[2]))
{ {
...@@ -3003,9 +3031,9 @@ ...@@ -3003,9 +3031,9 @@
(match_operand:QI 1 "general_operand" "imud")) (match_operand:QI 1 "general_operand" "imud"))
(match_operand:HI 2 "general_operand" "dimu")]))] (match_operand:HI 2 "general_operand" "dimu")]))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (reg:QI 6) (match_dup 6)) [(set (reg:QI B_REGNUM) (match_dup 6))
(set (reg:QI 5) (match_dup 4)) (set (reg:QI A_REGNUM) (match_dup 4))
(set (reg:QI 6) (match_op_dup 3 [(reg:QI 6) (match_dup 5)]))] (set (reg:QI B_REGNUM) (match_op_dup 3 [(reg:QI B_REGNUM) (match_dup 5)]))]
" "
PUT_MODE (operands[3], QImode); PUT_MODE (operands[3], QImode);
if (D_REG_P (operands[2])) if (D_REG_P (operands[2]))
...@@ -3034,8 +3062,8 @@ ...@@ -3034,8 +3062,8 @@
(match_operand:HI 2 "general_operand" "dimu") (match_operand:HI 2 "general_operand" "dimu")
(const_int 8))]))] (const_int 8))]))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (reg:QI 6) (match_dup 5)) [(set (reg:QI A_REGNUM) (match_dup 4))
(set (reg:QI 5) (match_dup 4))] (set (reg:QI B_REGNUM) (match_dup 5))]
" "
if (GET_CODE (operands[3]) == AND) if (GET_CODE (operands[3]) == AND)
{ {
...@@ -3074,9 +3102,9 @@ ...@@ -3074,9 +3102,9 @@
(const_int 16)) (const_int 16))
(match_operand:SI 2 "general_operand" "uim,0")]))] (match_operand:SI 2 "general_operand" "uim,0")]))]
"reload_completed" "reload_completed"
[(set (reg:HI 1) (match_dup 4)) [(set (reg:HI D_REGNUM) (match_dup 4))
(set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 5)])) (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 5)]))
(set (reg:HI 0) (match_dup 6))] (set (reg:HI X_REGNUM) (match_dup 6))]
"operands[5] = m68hc11_gen_highpart (HImode, operands[1]); "operands[5] = m68hc11_gen_highpart (HImode, operands[1]);
if (X_REG_P (operands[2])) if (X_REG_P (operands[2]))
{ {
...@@ -3110,11 +3138,11 @@ ...@@ -3110,11 +3138,11 @@
(const_int 16)) (const_int 16))
(match_operand:SI 2 "general_operand" "0,0")]))] (match_operand:SI 2 "general_operand" "0,0")]))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(parallel [(set (reg:HI 1) (reg:HI 0)) [(parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI 0) (reg:HI 1))]) (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])
(set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 4)])) (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 4)]))
(parallel [(set (reg:HI 1) (reg:HI 0)) (parallel [(set (reg:HI D_REGNUM) (reg:HI X_REGNUM))
(set (reg:HI 0) (reg:HI 1))])] (set (reg:HI X_REGNUM) (reg:HI D_REGNUM))])]
"operands[4] = m68hc11_gen_lowpart (HImode, operands[1]); "operands[4] = m68hc11_gen_lowpart (HImode, operands[1]);
PUT_MODE (operands[3], HImode);") PUT_MODE (operands[3], HImode);")
...@@ -3177,17 +3205,19 @@ ...@@ -3177,17 +3205,19 @@
/* If we are adding a small constant to X or Y, it's /* If we are adding a small constant to X or Y, it's
better to use one or several inx/iny instructions. */ better to use one or several inx/iny instructions. */
&& !(GET_CODE (operands[3]) == PLUS && !(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 || (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) >= -4 && INTVAL (operands[2]) >= -4
&& INTVAL (operands[2]) <= 4)))" && INTVAL (operands[2]) <= 4)))"
[(set (match_dup 4) (match_dup 5)) [(set (match_dup 4) (match_dup 5))
(set (match_dup 8) (match_dup 7)) (set (match_dup 8) (match_dup 7))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 6)])) (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 6)]))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
" "
/* Save the operand2 in a temporary location and use it. */ /* Save the operand2 in a temporary location and use it. */
if (H_REG_P (operands[2]) if (H_REG_P (operands[2])
...@@ -3224,16 +3254,18 @@ ...@@ -3224,16 +3254,18 @@
/* If we are adding a small constant to X or Y, it's /* If we are adding a small constant to X or Y, it's
better to use one or several inx/iny instructions. */ better to use one or several inx/iny instructions. */
&& !(GET_CODE (operands[3]) == PLUS && !(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 || (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) >= -4 && INTVAL (operands[2]) >= -4
&& INTVAL (operands[2]) <= 4)))" && INTVAL (operands[2]) <= 4)))"
[(set (match_dup 0) (match_dup 1)) [(set (match_dup 0) (match_dup 1))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI 1) (match_op_dup 3 [(reg:HI 1) (match_dup 2)])) (set (reg:HI D_REGNUM) (match_op_dup 3 [(reg:HI D_REGNUM) (match_dup 2)]))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
" "
") ")
...@@ -3283,11 +3315,11 @@ ...@@ -3283,11 +3315,11 @@
[(match_operand 1 "general_operand" "uim*d*A")]))] [(match_operand 1 "general_operand" "uim*d*A")]))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (match_dup 4) (match_dup 5)) [(set (match_dup 4) (match_dup 5))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI 1) (match_op_dup 2 [(match_dup 3)])) (set (reg:HI D_REGNUM) (match_op_dup 2 [(match_dup 3)]))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
" "
{ {
if ((H_REG_P (operands[1]) if ((H_REG_P (operands[1])
...@@ -3331,11 +3363,11 @@ ...@@ -3331,11 +3363,11 @@
&& GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[2]) == CONST_INT
&& (INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == -1))" && (INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == -1))"
[(set (match_dup 5) (match_dup 6)) [(set (match_dup 5) (match_dup 6))
(parallel [(set (reg:HI 1) (match_dup 4)) (parallel [(set (reg:HI D_REGNUM) (match_dup 4))
(set (match_dup 4) (reg:HI 1))]) (set (match_dup 4) (reg:HI D_REGNUM))])
(set (reg:QI 1) (match_op_dup 3 [(reg:QI 1) (match_dup 7)])) (set (reg:QI D_REGNUM) (match_op_dup 3 [(reg:QI D_REGNUM) (match_dup 7)]))
(parallel [(set (reg:HI 1) (match_dup 4)) (parallel [(set (reg:HI D_REGNUM) (match_dup 4))
(set (match_dup 4) (reg:HI 1))])] (set (match_dup 4) (reg:HI D_REGNUM))])]
"operands[4] = gen_rtx (REG, HImode, REGNO (operands[0])); "operands[4] = gen_rtx (REG, HImode, REGNO (operands[0]));
/* For the second operand is a hard register or if the address /* For the second operand is a hard register or if the address
...@@ -3410,11 +3442,11 @@ ...@@ -3410,11 +3442,11 @@
[(match_operand:QI 1 "general_operand" "uim*d*x*y")]))] [(match_operand:QI 1 "general_operand" "uim*d*x*y")]))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (match_dup 4) (match_dup 5)) [(set (match_dup 4) (match_dup 5))
(parallel [(set (reg:HI 1) (match_dup 3)) (parallel [(set (reg:HI D_REGNUM) (match_dup 3))
(set (match_dup 3) (reg:HI 1))]) (set (match_dup 3) (reg:HI D_REGNUM))])
(set (reg:QI 1) (match_op_dup 2 [(match_dup 6)])) (set (reg:QI D_REGNUM) (match_op_dup 2 [(match_dup 6)]))
(parallel [(set (reg:HI 1) (match_dup 3)) (parallel [(set (reg:HI D_REGNUM) (match_dup 3))
(set (match_dup 3) (reg:HI 1))])] (set (match_dup 3) (reg:HI D_REGNUM))])]
" "
{ {
operands[3] = gen_rtx (REG, HImode, REGNO (operands[0])); operands[3] = gen_rtx (REG, HImode, REGNO (operands[0]));
...@@ -3530,12 +3562,12 @@ ...@@ -3530,12 +3562,12 @@
(not:SI (match_operand:SI 1 "non_push_operand" "0")))] (not:SI (match_operand:SI 1 "non_push_operand" "0")))]
"z_replacement_completed == 2 "z_replacement_completed == 2
&& (!D_REG_P (operands[0]) || (optimize && optimize_size == 0))" && (!D_REG_P (operands[0]) || (optimize && optimize_size == 0))"
[(set (reg:HI 1) (not:HI (reg:HI 1))) [(set (reg:HI D_REGNUM) (not:HI (reg:HI D_REGNUM)))
(parallel [(set (reg:HI 0) (reg:HI 1)) (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
(set (reg:HI 1) (reg:HI 0))]) (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])
(set (reg:HI 1) (not:HI (reg:HI 1))) (set (reg:HI D_REGNUM) (not:HI (reg:HI D_REGNUM)))
(parallel [(set (reg:HI 0) (reg:HI 1)) (parallel [(set (reg:HI X_REGNUM) (reg:HI D_REGNUM))
(set (reg:HI 1) (reg:HI 0))])] (set (reg:HI D_REGNUM) (reg:HI X_REGNUM))])]
" "
{ {
/* The result pattern only works for D register. /* The result pattern only works for D register.
...@@ -3623,15 +3655,15 @@ ...@@ -3623,15 +3655,15 @@
(set (match_dup 4) (match_dup 2)) (set (match_dup 4) (match_dup 2))
(set (match_dup 2) (match_dup 5)) (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 6) (match_dup 2))
(set (match_dup 2) (match_dup 7)) (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 8) (match_dup 2))
(set (match_dup 2) (match_dup 9)) (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))] (set (match_dup 10) (match_dup 2))]
"operands[3] = m68hc11_gen_lowpart (SImode, operands[1]); "operands[3] = m68hc11_gen_lowpart (SImode, operands[1]);
operands[5] = m68hc11_gen_highpart (HImode, operands[3]); operands[5] = m68hc11_gen_highpart (HImode, operands[3]);
...@@ -3663,8 +3695,8 @@ ...@@ -3663,8 +3695,8 @@
(const_int 16)) (const_int 16))
(match_operand:SI 2 "general_operand" "0")))] (match_operand:SI 2 "general_operand" "0")))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (reg:HI 1) (plus:HI (reg:HI 1) (match_dup 3))) [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3)))
(set (reg:HI 0) (plus:HI (plus:HI (reg:HI 0) (const_int 0)) (reg:HI 7)))] (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]);") "operands[3] = m68hc11_gen_highpart (HImode, operands[1]);")
(define_insn "addsi_ashift16" (define_insn "addsi_ashift16"
...@@ -3685,7 +3717,7 @@ ...@@ -3685,7 +3717,7 @@
(match_operand:SI 1 "general_operand" "0"))) (match_operand:SI 1 "general_operand" "0")))
(clobber (match_scratch:HI 3 "=X"))] (clobber (match_scratch:HI 3 "=X"))]
"0 && reload_completed && z_replacement_completed == 2" "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]); operands[4] = m68hc11_gen_lowpart (HImode, operands[2]);
...@@ -3705,8 +3737,8 @@ ...@@ -3705,8 +3737,8 @@
(const_int 65535)) (const_int 65535))
(match_operand:SI 2 "general_operand" "0")))] (match_operand:SI 2 "general_operand" "0")))]
"z_replacement_completed == 2" "z_replacement_completed == 2"
[(set (reg:HI 1) (plus:HI (reg:HI 1) (match_dup 3))) [(set (reg:HI D_REGNUM) (plus:HI (reg:HI D_REGNUM) (match_dup 3)))
(set (reg:HI 0) (plus:HI (plus:HI (reg:HI 0) (const_int 0)) (reg:HI 7)))] (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]);") "operands[3] = m68hc11_gen_lowpart (HImode, operands[1]);")
;; ;;
...@@ -3766,8 +3798,8 @@ ...@@ -3766,8 +3798,8 @@
(const_int 16))) (const_int 16)))
(clobber (match_scratch:HI 2 "=X"))] (clobber (match_scratch:HI 2 "=X"))]
"reload_completed" "reload_completed"
[(set (reg:HI 0) (match_dup 1)) [(set (reg:HI X_REGNUM) (match_dup 1))
(set (reg:HI 1) (const_int 0))] (set (reg:HI D_REGNUM) (const_int 0))]
"") "")
(define_insn "*ashlsi3_const1" (define_insn "*ashlsi3_const1"
...@@ -3910,7 +3942,7 @@ ...@@ -3910,7 +3942,7 @@
(define_insn "*ashlhi3_2" (define_insn "*ashlhi3_2"
[(set (match_operand:HI 0 "register_operand" "=d") [(set (match_operand:HI 0 "register_operand" "=d")
(ashift:HI (match_operand:HI 1 "register_operand" "0") (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))] (clobber (match_dup 2))]
"" ""
"* "*
...@@ -3919,10 +3951,10 @@ ...@@ -3919,10 +3951,10 @@
return \"bsr\\t___lshlhi3\"; return \"bsr\\t___lshlhi3\";
}") }")
(define_insn "" (define_insn "*ashlhi3"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
(ashift:HI (match_dup 0) (ashift:HI (match_dup 0)
(match_operand:HI 1 "register_operand" "x"))) (match_operand:HI 1 "register_operand" "+x")))
(clobber (match_dup 1))] (clobber (match_dup 1))]
"" ""
"* "*
...@@ -4177,9 +4209,9 @@ ...@@ -4177,9 +4209,9 @@
output_asm_insn (\"rolb\", operands); output_asm_insn (\"rolb\", operands);
output_asm_insn (\"rola\", operands); output_asm_insn (\"rola\", operands);
output_asm_insn (\"tab\", 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 (\"bcc\\t%l0\", ops);
output_asm_insn (\"oraa\\t#0xFE\", ops); output_asm_insn (\"coma\", ops);
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
CODE_LABEL_NUMBER (ops[0])); CODE_LABEL_NUMBER (ops[0]));
...@@ -4199,7 +4231,7 @@ ...@@ -4199,7 +4231,7 @@
(define_insn "*ashrhi3" (define_insn "*ashrhi3"
[(set (match_operand:HI 0 "register_operand" "=d,x") [(set (match_operand:HI 0 "register_operand" "=d,x")
(ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0") (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))] (clobber (match_dup 2))]
"" ""
"* "*
...@@ -4387,14 +4419,14 @@ ...@@ -4387,14 +4419,14 @@
(match_operand:DI 2 "const_int_operand" ""))) (match_operand:DI 2 "const_int_operand" "")))
(clobber (match_scratch:HI 3 "=d"))] (clobber (match_scratch:HI 3 "=d"))]
"z_replacement_completed && INTVAL (operands[2]) >= 56" "z_replacement_completed && INTVAL (operands[2]) >= 56"
[(set (reg:QI 1) (match_dup 9)) [(set (reg:QI D_REGNUM) (match_dup 9))
(set (reg:QI 1) (lshiftrt:QI (reg:QI 1) (match_dup 8))) (set (reg:QI D_REGNUM) (lshiftrt:QI (reg:QI D_REGNUM) (match_dup 8)))
(set (reg:HI 1) (zero_extend:HI (reg:QI 1))) (set (reg:HI D_REGNUM) (zero_extend:HI (reg:QI D_REGNUM)))
(set (match_dup 4) (reg:HI 1)) (set (match_dup 4) (reg:HI D_REGNUM))
(set (reg:QI 1) (const_int 0)) (set (reg:QI D_REGNUM) (const_int 0))
(set (match_dup 5) (reg:HI 1)) (set (match_dup 5) (reg:HI D_REGNUM))
(set (match_dup 6) (reg:HI 1)) (set (match_dup 6) (reg:HI D_REGNUM))
(set (match_dup 7) (reg:HI 1))] (set (match_dup 7) (reg:HI D_REGNUM))]
"operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 56); "operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 56);
operands[4] = m68hc11_gen_lowpart (SImode, operands[0]); operands[4] = m68hc11_gen_lowpart (SImode, operands[0]);
operands[5] = m68hc11_gen_highpart (HImode, operands[4]); operands[5] = m68hc11_gen_highpart (HImode, operands[4]);
...@@ -4415,13 +4447,13 @@ ...@@ -4415,13 +4447,13 @@
(clobber (match_scratch:HI 3 "=d"))] (clobber (match_scratch:HI 3 "=d"))]
"z_replacement_completed && INTVAL (operands[2]) >= 48 "z_replacement_completed && INTVAL (operands[2]) >= 48
&& INTVAL (operands[2]) < 56" && INTVAL (operands[2]) < 56"
[(set (reg:HI 1) (match_dup 9)) [(set (reg:HI D_REGNUM) (match_dup 9))
(set (reg:HI 1) (lshiftrt:HI (reg:HI 1) (match_dup 8))) (set (reg:HI D_REGNUM) (lshiftrt:HI (reg:HI D_REGNUM) (match_dup 8)))
(set (match_dup 4) (reg:HI 1)) (set (match_dup 4) (reg:HI D_REGNUM))
(set (reg:HI 1) (const_int 0)) (set (reg:HI D_REGNUM) (const_int 0))
(set (match_dup 5) (reg:HI 1)) (set (match_dup 5) (reg:HI D_REGNUM))
(set (match_dup 6) (reg:HI 1)) (set (match_dup 6) (reg:HI D_REGNUM))
(set (match_dup 7) (reg:HI 1))] (set (match_dup 7) (reg:HI D_REGNUM))]
"operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 48); "operands[8] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) - 48);
operands[4] = m68hc11_gen_lowpart (SImode, operands[0]); operands[4] = m68hc11_gen_lowpart (SImode, operands[0]);
operands[5] = m68hc11_gen_highpart (HImode, operands[4]); operands[5] = m68hc11_gen_highpart (HImode, operands[4]);
...@@ -4452,15 +4484,15 @@ ...@@ -4452,15 +4484,15 @@
(set (match_dup 4) (match_dup 2)) (set (match_dup 4) (match_dup 2))
(set (match_dup 2) (match_dup 5)) (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 6) (match_dup 2))
(set (match_dup 2) (match_dup 7)) (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 8) (match_dup 2))
(set (match_dup 2) (match_dup 9)) (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))] (set (match_dup 10) (match_dup 2))]
"operands[3] = m68hc11_gen_highpart (SImode, operands[1]); "operands[3] = m68hc11_gen_highpart (SImode, operands[1]);
operands[5] = m68hc11_gen_lowpart (HImode, operands[3]); operands[5] = m68hc11_gen_lowpart (HImode, operands[3]);
...@@ -4508,8 +4540,10 @@ ...@@ -4508,8 +4540,10 @@
(const_int 16))) (const_int 16)))
(clobber (match_scratch:HI 2 "=X,X,X,X"))] (clobber (match_scratch:HI 2 "=X,X,X,X"))]
"" ""
"# "@
#
xgdx\\n\\tldx\\t#0 xgdx\\n\\tldx\\t#0
#
#") #")
(define_insn "*lshrsi3_const1" (define_insn "*lshrsi3_const1"
...@@ -4727,7 +4761,7 @@ ...@@ -4727,7 +4761,7 @@
(define_insn "*lshrhi3" (define_insn "*lshrhi3"
[(set (match_operand:HI 0 "register_operand" "=d,x") [(set (match_operand:HI 0 "register_operand" "=d,x")
(lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0") (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))] (clobber (match_dup 2))]
"" ""
"* "*
...@@ -4868,7 +4902,7 @@ ...@@ -4868,7 +4902,7 @@
(define_insn "*rotlqi3_with_carry" (define_insn "*rotlqi3_with_carry"
[(set (match_operand:QI 0 "register_operand" "=d,!q") [(set (match_operand:QI 0 "register_operand" "=d,!q")
(rotate:QI (match_operand:QI 1 "register_operand" "0,0") (rotate:QI (match_operand:QI 1 "register_operand" "0,0")
(reg:QI 7)))] (reg:QI CC_REGNUM)))]
"" ""
"* "*
{ {
...@@ -4881,7 +4915,7 @@ ...@@ -4881,7 +4915,7 @@
(define_insn "*rotlhi3_with_carry" (define_insn "*rotlhi3_with_carry"
[(set (match_operand:HI 0 "register_operand" "=d") [(set (match_operand:HI 0 "register_operand" "=d")
(rotate:HI (match_operand:HI 1 "register_operand" "0") (rotate:HI (match_operand:HI 1 "register_operand" "0")
(reg:HI 7)))] (reg:HI CC_REGNUM)))]
"" ""
"* "*
{ {
...@@ -4892,7 +4926,7 @@ ...@@ -4892,7 +4926,7 @@
(define_insn "*rotrhi3_with_carry" (define_insn "*rotrhi3_with_carry"
[(set (match_operand:HI 0 "register_operand" "=d") [(set (match_operand:HI 0 "register_operand" "=d")
(rotatert:HI (match_operand:HI 1 "register_operand" "0") (rotatert:HI (match_operand:HI 1 "register_operand" "0")
(reg:HI 7)))] (reg:HI CC_REGNUM)))]
"" ""
"* "*
{ {
...@@ -5328,7 +5362,7 @@ ...@@ -5328,7 +5362,7 @@
;; ;;
;;- Call a function that returns no value. ;;- Call a function that returns no value.
(define_insn "call" (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"))] (match_operand:SI 1 "general_operand" "g"))]
;; Operand 1 not really used on the m68hc11. ;; Operand 1 not really used on the m68hc11.
"" ""
...@@ -5349,7 +5383,7 @@ ...@@ -5349,7 +5383,7 @@
(define_insn "call_value" (define_insn "call_value"
[(set (match_operand 0 "" "=g") [(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")))] (match_operand:SI 2 "general_operand" "g")))]
"" ""
"* "*
...@@ -5478,7 +5512,7 @@ ...@@ -5478,7 +5512,7 @@
(define_insn "*return_16bit" (define_insn "*return_16bit"
[(return) [(return)
(use (reg:HI 1))] (use (reg:HI D_REGNUM))]
"reload_completed && m68hc11_total_frame_size () == 0" "reload_completed && m68hc11_total_frame_size () == 0"
"* "*
{ {
...@@ -5545,13 +5579,13 @@ ...@@ -5545,13 +5579,13 @@
(define_peephole (define_peephole
[(set (match_operand:HI 0 "hard_reg_operand" "xy") [(set (match_operand:HI 0 "hard_reg_operand" "xy")
(match_operand:HI 1 "const_int_operand" "")) (match_operand:HI 1 "const_int_operand" ""))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI 1) (set (reg:HI D_REGNUM)
(plus (reg:HI 1) (plus (reg:HI D_REGNUM)
(match_operand:HI 2 "general_operand" ""))) (match_operand:HI 2 "general_operand" "")))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
"(INTVAL (operands[1]) & 0x0FF) == 0" "(INTVAL (operands[1]) & 0x0FF) == 0"
"* "*
{ {
...@@ -5634,9 +5668,9 @@ ...@@ -5634,9 +5668,9 @@
;; (set ...) insn. ;; (set ...) insn.
;; ;;
(define_peephole (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))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
"find_regno_note (ins1, REG_DEAD, HARD_D_REGNUM)" "find_regno_note (ins1, REG_DEAD, HARD_D_REGNUM)"
"* "*
{ {
...@@ -5648,10 +5682,10 @@ ...@@ -5648,10 +5682,10 @@
;; Same as above but due to some split, there may be a noop set ;; Same as above but due to some split, there may be a noop set
;; between the two. ;; between the two.
(define_peephole (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)) (set (match_dup 0) (match_dup 0))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
"find_regno_note (ins1, REG_DEAD, HARD_D_REGNUM)" "find_regno_note (ins1, REG_DEAD, HARD_D_REGNUM)"
"* "*
{ {
...@@ -5665,9 +5699,9 @@ ...@@ -5665,9 +5699,9 @@
;; and we must, at least, setup X/Y with value of D. ;; and we must, at least, setup X/Y with value of D.
;; ;;
(define_peephole (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))
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
"" ""
"* "*
{ {
...@@ -5685,9 +5719,9 @@ ...@@ -5685,9 +5719,9 @@
;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. ;;; need to emit anything. Otherwise, we just need an copy of D to X/Y.
;;; ;;;
(define_peephole (define_peephole
[(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI 1) (match_dup 0))] (set (reg:HI D_REGNUM) (match_dup 0))]
"find_regno_note (insn, REG_DEAD, REGNO (operands[0]))" "find_regno_note (insn, REG_DEAD, REGNO (operands[0]))"
"* "*
{ {
...@@ -5701,9 +5735,9 @@ ...@@ -5701,9 +5735,9 @@
;;; need to emit anything. Otherwise, we just need an copy of D to X/Y. ;;; need to emit anything. Otherwise, we just need an copy of D to X/Y.
;;; ;;;
(define_peephole (define_peephole
[(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:QI 1) (match_operand:QI 1 "hard_reg_operand" "A"))] (set (reg:QI D_REGNUM) (match_operand:QI 1 "hard_reg_operand" "A"))]
"REGNO (operands[0]) == REGNO (operands[1]) "REGNO (operands[0]) == REGNO (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[0]))" && find_regno_note (insn, REG_DEAD, REGNO (operands[0]))"
"* "*
...@@ -5718,9 +5752,9 @@ ...@@ -5718,9 +5752,9 @@
;;; need to emit anything. Otherwise, we just need a copy of D to X/Y. ;;; need to emit anything. Otherwise, we just need a copy of D to X/Y.
;;; ;;;
(define_peephole (define_peephole
[(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:HI 1) (match_dup 0))] (set (reg:HI D_REGNUM) (match_dup 0))]
"" ""
"* "*
{ {
...@@ -5738,9 +5772,9 @@ ...@@ -5738,9 +5772,9 @@
;;; with the xgdx. ;;; with the xgdx.
;;; ;;;
(define_peephole (define_peephole
[(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(set (reg:QI 1) (match_operand:QI 1 "hard_reg_operand" "A"))] (set (reg:QI D_REGNUM) (match_operand:QI 1 "hard_reg_operand" "A"))]
"REGNO (operands[0]) == REGNO (operands[1])" "REGNO (operands[0]) == REGNO (operands[1])"
"* "*
{ {
...@@ -5757,10 +5791,10 @@ ...@@ -5757,10 +5791,10 @@
;;; Catch two consecutive xgdx or xgdy, emit nothing. ;;; Catch two consecutive xgdx or xgdy, emit nothing.
;;; ;;;
(define_peephole (define_peephole
[(parallel [(set (reg:HI 1) (match_operand:HI 0 "hard_reg_operand" "A")) [(parallel [(set (reg:HI D_REGNUM) (match_operand:HI 0 "hard_reg_operand" "A"))
(set (match_dup 0) (reg:HI 1))]) (set (match_dup 0) (reg:HI D_REGNUM))])
(parallel [(set (reg:HI 1) (match_dup 0)) (parallel [(set (reg:HI D_REGNUM) (match_dup 0))
(set (match_dup 0) (reg:HI 1))])] (set (match_dup 0) (reg:HI D_REGNUM))])]
"" ""
"* "*
{ {
...@@ -5834,7 +5868,7 @@ ...@@ -5834,7 +5868,7 @@
;; ;;
(define_peephole (define_peephole
[(set (match_operand:HI 0 "hard_reg_operand" "dA") (const_int -1)) [(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" "TARGET_M6811"
"* "*
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment