Commit 5e04daf3 by Peter Barada Committed by Bernardo Innocenti

m68k.md (movsi_cfv4): New pattern to allow mov3q.

	* config/m68k/m68k.md (movsi_cfv4): New pattern to allow mov3q.
	(movsi_cf): Make named, don't match TARGET_CFV4.
	(pushexthisi_const): Use mov3q if possible.
	(extendhisi2, cvf4_extendhisi2): Split extendhisi2 pattern
	to special case mvz.w for ColdFire V4.
	(extendqisi2, cvf4_extendqisi2): Split extendhisi2 pattern
	to special case mvz.b for ColdFire V4.
	(udivmodhi4, divmodhi4): Use mvz to zero extend arg for
	divide.
	(iorsi3, xorsi3, andsi3): Use bitfield instructions if possible.
	* config/m68k/m68k.c(valid_mov3q_const):  New function.
	(const_method): SWAP is valid for ColdFire.
	(MULL_COST, MULW_COST): Fix costs for ColdFire V3/V4.
	* config/m68k/m68k-protos.h (valid_mov3q_const): Prototype here.

From-SVN: r83266
parent 8c161995
2004-06-15 Peter Barada <peter@the-baradas.com>
* config/m68k/m68k.md (movsi_cfv4): New pattern to allow mov3q.
(movsi_cf): Make named, don't match TARGET_CFV4.
(pushexthisi_const): Use mov3q if possible.
(extendhisi2, cvf4_extendhisi2): Split extendhisi2 pattern
to special case mvz.w for ColdFire V4.
(extendqisi2, cvf4_extendqisi2): Split extendhisi2 pattern
to special case mvz.b for ColdFire V4.
(udivmodhi4, divmodhi4): Use mvz to zero extend arg for
divide.
(iorsi3, xorsi3, andsi3): Use bitfield instructions if possible.
* config/m68k/m68k.c(valid_mov3q_const): New function.
(const_method): SWAP is valid for ColdFire.
(MULL_COST, MULW_COST): Fix costs for ColdFire V3/V4.
* config/m68k/m68k-protos.h (valid_mov3q_const): Prototype here.
2004-06-16 Richard Henderson <rth@redhat.com> 2004-06-16 Richard Henderson <rth@redhat.com>
* c-common.def (CASE_LABEL): Remove. * c-common.def (CASE_LABEL): Remove.
......
/* Definitions of target machine for GNU compiler. Sun 68000/68020 version. /* Definitions of target machine for GNU compiler. Sun 68000/68020 version.
Copyright (C) 2000, 2002 Free Software Foundation, Inc. Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
#ifdef RTX_CODE #ifdef RTX_CODE
extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to); extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to);
extern const char *output_move_const_into_data_reg (rtx *); extern const char *output_move_const_into_data_reg (rtx *);
extern int valid_mov3q_const (rtx);
extern const char *output_move_simode_const (rtx *); extern const char *output_move_simode_const (rtx *);
extern const char *output_move_simode (rtx *); extern const char *output_move_simode (rtx *);
extern const char *output_move_himode (rtx *); extern const char *output_move_himode (rtx *);
......
...@@ -1447,11 +1447,12 @@ const_method (rtx constant) ...@@ -1447,11 +1447,12 @@ const_method (rtx constant)
/* This is the only value where neg.w is useful */ /* This is the only value where neg.w is useful */
if (i == -65408) if (i == -65408)
return NEGW; return NEGW;
/* Try also with swap */ }
/* Try also with swap. */
u = i; u = i;
if (USE_MOVQ ((u >> 16) | (u << 16))) if (USE_MOVQ ((u >> 16) | (u << 16)))
return SWAP; return SWAP;
}
if (TARGET_CFV4) if (TARGET_CFV4)
{ {
...@@ -1524,9 +1525,9 @@ m68k_rtx_costs (rtx x, int code, int outer_code, int *total) ...@@ -1524,9 +1525,9 @@ m68k_rtx_costs (rtx x, int code, int outer_code, int *total)
for add and the time for shift, taking away a little more because for add and the time for shift, taking away a little more because
sometimes move insns are needed. */ sometimes move insns are needed. */
/* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */ /* div?.w is relatively cheaper on 68000 counted in COSTS_N_INSNS terms. */
#define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : TARGET_CFV3 ? 3 : TARGET_COLDFIRE ? 10 : 13) #define MULL_COST (TARGET_68060 ? 2 : TARGET_68040 ? 5 : (TARGET_COLDFIRE && !TARGET_5200) ? 3 : TARGET_COLDFIRE ? 10 : 13)
#define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \ #define MULW_COST (TARGET_68060 ? 2 : TARGET_68040 ? 3 : TARGET_68020 ? 8 : \
TARGET_CFV3 ? 2 : 5) (TARGET_COLDFIRE && !TARGET_5200) ? 2 : 5)
#define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12) #define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12)
case PLUS: case PLUS:
...@@ -1651,6 +1652,23 @@ output_move_const_into_data_reg (rtx *operands) ...@@ -1651,6 +1652,23 @@ output_move_const_into_data_reg (rtx *operands)
} }
} }
/* Return 1 if 'constant' can be represented by
mov3q on a ColdFire V4 core. */
int
valid_mov3q_const (rtx constant)
{
int i;
if (TARGET_CFV4 && GET_CODE (constant) == CONST_INT)
{
i = INTVAL (constant);
if ((i == -1) || (i >= 1 && i <= 7))
return 1;
}
return 0;
}
const char * const char *
output_move_simode_const (rtx *operands) output_move_simode_const (rtx *operands)
{ {
...@@ -1663,6 +1681,9 @@ output_move_simode_const (rtx *operands) ...@@ -1663,6 +1681,9 @@ output_move_simode_const (rtx *operands)
|| !(GET_CODE (operands[0]) == MEM || !(GET_CODE (operands[0]) == MEM
&& MEM_VOLATILE_P (operands[0])))) && MEM_VOLATILE_P (operands[0]))))
return "clr%.l %0"; return "clr%.l %0";
else if ((GET_MODE (operands[0]) == SImode)
&& valid_mov3q_const (operands[1]))
return "mov3q%.l %1,%0";
else if (operands[1] == const0_rtx else if (operands[1] == const0_rtx
&& ADDRESS_REG_P (operands[0])) && ADDRESS_REG_P (operands[0]))
return "sub%.l %0,%0"; return "sub%.l %0,%0";
...@@ -1671,13 +1692,21 @@ output_move_simode_const (rtx *operands) ...@@ -1671,13 +1692,21 @@ output_move_simode_const (rtx *operands)
else if (ADDRESS_REG_P (operands[0]) else if (ADDRESS_REG_P (operands[0])
&& INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) < 0x8000
&& INTVAL (operands[1]) >= -0x8000) && INTVAL (operands[1]) >= -0x8000)
{
if (valid_mov3q_const (operands[1]))
return "mov3q%.l %1,%0";
return "move%.w %1,%0"; return "move%.w %1,%0";
}
else if (GET_CODE (operands[0]) == MEM else if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == PRE_DEC && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
&& REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
&& INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) < 0x8000
&& INTVAL (operands[1]) >= -0x8000) && INTVAL (operands[1]) >= -0x8000)
{
if (valid_mov3q_const (operands[1]))
return "mov3q%.l %1,%-";
return "pea %a1"; return "pea %a1";
}
return "move%.l %1,%0"; return "move%.l %1,%0";
} }
......
...@@ -587,6 +587,8 @@ ...@@ -587,6 +587,8 @@
{ {
if (operands[1] == const0_rtx) if (operands[1] == const0_rtx)
return "clr%.l %0"; return "clr%.l %0";
if (valid_mov3q_const(operands[1]))
return "mov3q%.l %1,%-";
return "pea %a1"; return "pea %a1";
}) })
...@@ -675,10 +677,16 @@ ...@@ -675,10 +677,16 @@
return output_move_simode (operands); return output_move_simode (operands);
}) })
(define_insn "" (define_insn "*movsi_cf"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U") [(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
(match_operand:SI 1 "general_operand" "g,r<Q>,U"))] (match_operand:SI 1 "general_operand" "g,r<Q>,U"))]
"TARGET_COLDFIRE" "TARGET_COLDFIRE && !TARGET_CFV4"
"* return output_move_simode (operands);")
(define_insn "*movsi_cfv4"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r<Q>,g,U")
(match_operand:SI 1 "general_operand" "Rg,Rr<Q>,U"))]
"TARGET_CFV4"
"* return output_move_simode (operands);") "* return output_move_simode (operands);")
;; Special case of fullword move, where we need to get a non-GOT PIC ;; Special case of fullword move, where we need to get a non-GOT PIC
...@@ -1250,6 +1258,8 @@ ...@@ -1250,6 +1258,8 @@
{ {
if (DATA_REG_P (operands[0])) if (DATA_REG_P (operands[0]))
{ {
if (TARGET_CFV4)
return "mvz%.w %1,%0";
if (GET_CODE (operands[1]) == REG if (GET_CODE (operands[1]) == REG
&& REGNO (operands[0]) == REGNO (operands[1])) && REGNO (operands[0]) == REGNO (operands[1]))
return "and%.l #0xFFFF,%0"; return "and%.l #0xFFFF,%0";
...@@ -1280,10 +1290,18 @@ ...@@ -1280,10 +1290,18 @@
{ {
if (GET_CODE (operands[1]) == REG if (GET_CODE (operands[1]) == REG
&& REGNO (operands[0]) == REGNO (operands[1])) && REGNO (operands[0]) == REGNO (operands[1]))
{
if (TARGET_CFV4)
return "mvz%.b %0,%0";
return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0"); return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0");
}
if (reg_mentioned_p (operands[0], operands[1])) if (reg_mentioned_p (operands[0], operands[1]))
{
if (TARGET_CFV4)
return "mvz%.b %1,%0";
return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0" return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0"
: "move%.b %1,%0\;and%.l #0xFF,%0"); : "move%.b %1,%0\;and%.l #0xFF,%0");
}
return "clr%.w %0\;move%.b %1,%0"; return "clr%.w %0\;move%.b %1,%0";
} }
else if (GET_CODE (operands[0]) == MEM else if (GET_CODE (operands[0]) == MEM
...@@ -1318,6 +1336,8 @@ ...@@ -1318,6 +1336,8 @@
{ {
if (DATA_REG_P (operands[0])) if (DATA_REG_P (operands[0]))
{ {
if (TARGET_CFV4)
return "mvz%.b %1,%0";
if (GET_CODE (operands[1]) == REG if (GET_CODE (operands[1]) == REG
&& REGNO (operands[0]) == REGNO (operands[1])) && REGNO (operands[0]) == REGNO (operands[1]))
return "and%.l #0xFF,%0"; return "and%.l #0xFF,%0";
...@@ -1358,6 +1378,8 @@ ...@@ -1358,6 +1378,8 @@
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
if (TARGET_CFV4)
return "mvs%.b %1,%2\;smi %0\;extb%.l %0";
if (TARGET_68020 || TARGET_COLDFIRE) if (TARGET_68020 || TARGET_COLDFIRE)
return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0"; return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0";
else else
...@@ -1372,6 +1394,8 @@ ...@@ -1372,6 +1394,8 @@
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
if (TARGET_CFV4)
return "mvs%.w %1,%2\;smi %0\;extb%.l %0";
if (TARGET_68020 || TARGET_COLDFIRE) if (TARGET_68020 || TARGET_COLDFIRE)
return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0"; return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0";
else else
...@@ -1423,11 +1447,25 @@ ...@@ -1423,11 +1447,25 @@
return "smi %0\;ext%.w %0\;ext%.l %0"; return "smi %0\;ext%.w %0\;ext%.l %0";
}) })
(define_insn "extendhisi2" (define_expand "extendhisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(sign_extend:SI
(match_operand:HI 1 "nonimmediate_src_operand" "")))]
""
"")
(define_insn "*cfv4_extendhisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(sign_extend:SI
(match_operand:HI 1 "nonimmediate_src_operand" "rmS")))]
"TARGET_CFV4"
"mvs%.w %1,%0")
(define_insn "*68k_extendhisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a") [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,a")
(sign_extend:SI (sign_extend:SI
(match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))] (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))]
"" "!TARGET_CFV4"
{ {
if (ADDRESS_REG_P (operands[0])) if (ADDRESS_REG_P (operands[0]))
return "move%.w %1,%0"; return "move%.w %1,%0";
...@@ -1440,10 +1478,22 @@ ...@@ -1440,10 +1478,22 @@
"" ""
"ext%.w %0") "ext%.w %0")
(define_insn "extendqisi2" (define_expand "extendqisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
"TARGET_68020 || TARGET_COLDFIRE"
"")
(define_insn "*cfv4_extendqisi2"
[(set (match_operand:SI 0 "general_operand" "=d")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rms")))]
"TARGET_CFV4"
"mvs%.b %1,%0")
(define_insn "*68k_extendqisi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d") [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))]
"TARGET_68020 || TARGET_COLDFIRE" "TARGET_68020 || (TARGET_COLDFIRE && !TARGET_CFV4)"
"extb%.l %0") "extb%.l %0")
;; Conversions between float and double. ;; Conversions between float and double.
...@@ -2985,10 +3035,17 @@ ...@@ -2985,10 +3035,17 @@
(umod:HI (match_dup 1) (match_dup 2)))] (umod:HI (match_dup 1) (match_dup 2)))]
"!TARGET_COLDFIRE || TARGET_CF_HWDIV" "!TARGET_COLDFIRE || TARGET_CF_HWDIV"
{ {
if (TARGET_CFV4)
output_asm_insn (MOTOROLA ?
"mvz%.w %0,%0\;divu%.w %2,%0" :
"mvz%.w %0,%0\;divu %2,%0",
operands);
else
output_asm_insn (MOTOROLA ? output_asm_insn (MOTOROLA ?
"and%.l #0xFFFF,%0\;divu%.w %2,%0" : "and%.l #0xFFFF,%0\;divu%.w %2,%0" :
"and%.l #0xFFFF,%0\;divu %2,%0", "and%.l #0xFFFF,%0\;divu %2,%0",
operands); operands);
if (!find_reg_note(insn, REG_UNUSED, operands[3])) if (!find_reg_note(insn, REG_UNUSED, operands[3]))
{ {
CC_STATUS_INIT; CC_STATUS_INIT;
...@@ -3091,7 +3148,17 @@ ...@@ -3091,7 +3148,17 @@
(and:SI (match_operand:SI 1 "general_operand" "%0,0") (and:SI (match_operand:SI 1 "general_operand" "%0,0")
(match_operand:SI 2 "general_src_operand" "d,dmsK")))] (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
"TARGET_COLDFIRE" "TARGET_COLDFIRE"
"and%.l %2,%0") {
if (TARGET_CFV4 && DATA_REG_P (operands[0])
&& GET_CODE (operands[2]) == CONST_INT)
{
if (INTVAL (operands[2]) == 0x000000ff)
return \"mvz%.b %0,%0\";
else if (INTVAL (operands[2]) == 0x0000ffff)
return \"mvz%.w %0,%0\";
}
return output_andsi3 (operands);
})
(define_insn "andhi3" (define_insn "andhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "=m,d") [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
...@@ -3253,7 +3320,9 @@ ...@@ -3253,7 +3320,9 @@
(ior:SI (match_operand:SI 1 "general_operand" "%0,0") (ior:SI (match_operand:SI 1 "general_operand" "%0,0")
(match_operand:SI 2 "general_src_operand" "d,dmsK")))] (match_operand:SI 2 "general_src_operand" "d,dmsK")))]
"TARGET_COLDFIRE" "TARGET_COLDFIRE"
"or%.l %2,%0") {
return output_iorsi3 (operands);
})
(define_insn "iorhi3" (define_insn "iorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "=m,d") [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d")
...@@ -3432,7 +3501,9 @@ ...@@ -3432,7 +3501,9 @@
(xor:SI (match_operand:SI 1 "general_operand" "%0,0") (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
(match_operand:SI 2 "general_operand" "d,Ks")))] (match_operand:SI 2 "general_operand" "d,Ks")))]
"TARGET_COLDFIRE" "TARGET_COLDFIRE"
"eor%.l %2,%0") {
return output_xorsi3 (operands);
})
(define_insn "xorhi3" (define_insn "xorhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "=dm") [(set (match_operand:HI 0 "nonimmediate_operand" "=dm")
......
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