From 5e04daf3171dcb6095a9ee91fe09bf5a70df43a0 Mon Sep 17 00:00:00 2001 From: Peter Barada Date: Wed, 16 Jun 2004 21:53:46 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 17 ++++++ gcc/config/m68k/m68k-protos.h | 3 +- gcc/config/m68k/m68k.c | 45 ++++++++++++--- gcc/config/m68k/m68k.md | 103 ++++++++++++++++++++++++++++------ 4 files changed, 143 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02bd3ba8ff6..cb18ad6ea5b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2004-06-15 Peter Barada + + * 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 * c-common.def (CASE_LABEL): Remove. diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index 47afcb3762c..73810d72f82 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -1,5 +1,5 @@ /* 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. @@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ #ifdef RTX_CODE extern HOST_WIDE_INT m68k_initial_elimination_offset (int from, int to); 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 (rtx *); extern const char *output_move_himode (rtx *); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index da17f65f9cd..8ad252f91fa 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -1447,12 +1447,13 @@ const_method (rtx constant) /* This is the only value where neg.w is useful */ if (i == -65408) return NEGW; - /* Try also with swap */ - u = i; - if (USE_MOVQ ((u >> 16) | (u << 16))) - return SWAP; } + /* Try also with swap. */ + u = i; + if (USE_MOVQ ((u >> 16) | (u << 16))) + return SWAP; + if (TARGET_CFV4) { /* Try using MVZ/MVS with an immediate value to load constants. */ @@ -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 sometimes move insns are needed. */ /* 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 : \ - TARGET_CFV3 ? 2 : 5) + (TARGET_COLDFIRE && !TARGET_5200) ? 2 : 5) #define DIVW_COST (TARGET_68020 ? 27 : TARGET_CF_HWDIV ? 11 : 12) case PLUS: @@ -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 * output_move_simode_const (rtx *operands) { @@ -1663,6 +1681,9 @@ output_move_simode_const (rtx *operands) || !(GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[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 && ADDRESS_REG_P (operands[0])) return "sub%.l %0,%0"; @@ -1671,13 +1692,21 @@ output_move_simode_const (rtx *operands) else if (ADDRESS_REG_P (operands[0]) && INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) - return "move%.w %1,%0"; + { + if (valid_mov3q_const (operands[1])) + return "mov3q%.l %1,%0"; + return "move%.w %1,%0"; + } else if (GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM && INTVAL (operands[1]) < 0x8000 && INTVAL (operands[1]) >= -0x8000) - return "pea %a1"; + { + if (valid_mov3q_const (operands[1])) + return "mov3q%.l %1,%-"; + return "pea %a1"; + } return "move%.l %1,%0"; } diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index 2603195224d..2e24c113b2d 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -587,6 +587,8 @@ { if (operands[1] == const0_rtx) return "clr%.l %0"; + if (valid_mov3q_const(operands[1])) + return "mov3q%.l %1,%-"; return "pea %a1"; }) @@ -675,10 +677,16 @@ return output_move_simode (operands); }) -(define_insn "" +(define_insn "*movsi_cf" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,g,U") (match_operand:SI 1 "general_operand" "g,r,U"))] - "TARGET_COLDFIRE" + "TARGET_COLDFIRE && !TARGET_CFV4" + "* return output_move_simode (operands);") + +(define_insn "*movsi_cfv4" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,g,U") + (match_operand:SI 1 "general_operand" "Rg,Rr,U"))] + "TARGET_CFV4" "* return output_move_simode (operands);") ;; Special case of fullword move, where we need to get a non-GOT PIC @@ -1250,6 +1258,8 @@ { if (DATA_REG_P (operands[0])) { + if (TARGET_CFV4) + return "mvz%.w %1,%0"; if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1])) return "and%.l #0xFFFF,%0"; @@ -1280,10 +1290,18 @@ { if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1])) - return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0"); + { + if (TARGET_CFV4) + return "mvz%.b %0,%0"; + return (!TARGET_COLDFIRE ? "and%.w #0xFF,%0" : "and%.l #0xFF,%0"); + } if (reg_mentioned_p (operands[0], operands[1])) - return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0" - : "move%.b %1,%0\;and%.l #0xFF,%0"); + { + if (TARGET_CFV4) + return "mvz%.b %1,%0"; + return (!TARGET_COLDFIRE ? "move%.b %1,%0\;and%.w #0xFF,%0" + : "move%.b %1,%0\;and%.l #0xFF,%0"); + } return "clr%.w %0\;move%.b %1,%0"; } else if (GET_CODE (operands[0]) == MEM @@ -1318,6 +1336,8 @@ { if (DATA_REG_P (operands[0])) { + if (TARGET_CFV4) + return "mvz%.b %1,%0"; if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1])) return "and%.l #0xFF,%0"; @@ -1358,6 +1378,8 @@ { CC_STATUS_INIT; 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) return "move%.b %1,%2\;extb%.l %2\;smi %0\;extb%.l %0"; else @@ -1372,6 +1394,8 @@ { CC_STATUS_INIT; 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) return "move%.w %1,%2\;ext%.l %2\;smi %0\;extb%.l %0"; else @@ -1423,11 +1447,25 @@ 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") (sign_extend:SI (match_operand:HI 1 "nonimmediate_src_operand" "0,rmS")))] - "" + "!TARGET_CFV4" { if (ADDRESS_REG_P (operands[0])) return "move%.w %1,%0"; @@ -1440,10 +1478,22 @@ "" "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") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0")))] - "TARGET_68020 || TARGET_COLDFIRE" + "TARGET_68020 || (TARGET_COLDFIRE && !TARGET_CFV4)" "extb%.l %0") ;; Conversions between float and double. @@ -2985,10 +3035,17 @@ (umod:HI (match_dup 1) (match_dup 2)))] "!TARGET_COLDFIRE || TARGET_CF_HWDIV" { - output_asm_insn (MOTOROLA ? - "and%.l #0xFFFF,%0\;divu%.w %2,%0" : - "and%.l #0xFFFF,%0\;divu %2,%0", - operands); + 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 ? + "and%.l #0xFFFF,%0\;divu%.w %2,%0" : + "and%.l #0xFFFF,%0\;divu %2,%0", + operands); + if (!find_reg_note(insn, REG_UNUSED, operands[3])) { CC_STATUS_INIT; @@ -3091,7 +3148,17 @@ (and:SI (match_operand:SI 1 "general_operand" "%0,0") (match_operand:SI 2 "general_src_operand" "d,dmsK")))] "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" [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d") @@ -3253,7 +3320,9 @@ (ior:SI (match_operand:SI 1 "general_operand" "%0,0") (match_operand:SI 2 "general_src_operand" "d,dmsK")))] "TARGET_COLDFIRE" - "or%.l %2,%0") +{ + return output_iorsi3 (operands); +}) (define_insn "iorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=m,d") @@ -3432,7 +3501,9 @@ (xor:SI (match_operand:SI 1 "general_operand" "%0,0") (match_operand:SI 2 "general_operand" "d,Ks")))] "TARGET_COLDFIRE" - "eor%.l %2,%0") +{ + return output_xorsi3 (operands); +}) (define_insn "xorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=dm") -- 2.30.2