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