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>
* config.gcc(rs6000-ibm-aix|powerpc-ibm-aix): Do not include
......
/* 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:
; <A-high> 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
......
/* 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,
......
......@@ -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 = &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);
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)
......
......@@ -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
......
......@@ -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"
"*
{
......
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