Mercurial > hg > CbC > CbC_gcc
diff gcc/config/m68k/m68k.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 77e2b8dfacca |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/config/m68k/m68k.md Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/config/m68k/m68k.md Fri Oct 27 22:46:09 2017 +0900 @@ -1,7 +1,5 @@ ;;- Machine description for GNU compiler, Motorola 68000 Version -;; Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, -;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 -;; Free Software Foundation, Inc. +;; Copyright (C) 1987-2017 Free Software Foundation, Inc. ;; This file is part of GCC. @@ -124,6 +122,10 @@ (define_constants [(UNSPECV_BLOCKAGE 0) + (UNSPECV_CAS_1 1) + (UNSPECV_CAS_2 2) + (UNSPECV_TAS_1 3) + (UNSPECV_TAS_2 4) ]) ;; Registers by name. @@ -250,11 +252,15 @@ ;; Define 'enabled' attribute. (define_attr "enabled" "" - (cond [(and (ne (symbol_ref "TARGET_COLDFIRE") (const_int 0)) + (cond [(and (match_test "TARGET_COLDFIRE") (eq_attr "ok_for_coldfire" "no")) (const_int 0)] (const_int 1))) +;; Mode macros for integer operations. +(define_mode_iterator I [QI HI SI]) +(define_mode_attr sz [(QI "%.b") (HI "%.w") (SI "%.l")]) + ;; Mode macros for floating point operations. ;; Valid floating point modes (define_mode_iterator FP [SF DF (XF "TARGET_68881")]) @@ -483,10 +489,19 @@ ;; A composite of the cmp, cmpa, cmpi & cmpm m68000 op codes. +;; +;; In theory we ought to be able to use some 'S' constraints and +;; operand predicates that allow PC-rel addressing modes in the +;; comparison patterns and expanders below. But we would have to be +;; cognizant of the fact that PC-rel addresses are not allowed for +;; both operands and determining whether or not we emit the operands in +;; order or reversed is not trivial to do just based on the constraints +;; and operand predicates. So to be safe, just don't allow the PC-rel +;; versions in the various comparison expanders, patterns, for comparisons. (define_insn "" [(set (cc0) - (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mSr,mSa,>") - (match_operand:SI 1 "general_src_operand" "mSr,mSa,KTr,Ksr,>")))] + (compare (match_operand:SI 0 "nonimmediate_operand" "rKT,rKs,mr,ma,>") + (match_operand:SI 1 "general_operand" "mr,ma,KTr,Ksr,>")))] "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) @@ -523,7 +538,7 @@ (define_expand "cbranchhi4" [(set (cc0) - (compare (match_operand:HI 1 "nonimmediate_src_operand" "") + (compare (match_operand:HI 1 "nonimmediate_operand" "") (match_operand:HI 2 "m68k_subword_comparison_operand" ""))) (set (pc) (if_then_else (match_operator 0 "ordered_comparison_operator" @@ -545,8 +560,8 @@ (define_insn "" [(set (cc0) - (compare (match_operand:HI 0 "nonimmediate_src_operand" "rnmS,d,n,mS,>") - (match_operand:HI 1 "general_src_operand" "d,rnmS,mS,n,>")))] + (compare (match_operand:HI 0 "nonimmediate_operand" "rnm,d,n,m,>") + (match_operand:HI 1 "general_operand" "d,rnm,m,n,>")))] "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) @@ -562,7 +577,7 @@ (define_expand "cbranchqi4" [(set (cc0) - (compare (match_operand:QI 1 "nonimmediate_src_operand" "") + (compare (match_operand:QI 1 "nonimmediate_operand" "") (match_operand:QI 2 "m68k_subword_comparison_operand" ""))) (set (pc) (if_then_else (match_operator 0 "ordered_comparison_operator" @@ -574,7 +589,7 @@ (define_expand "cstoreqi4" [(set (cc0) - (compare (match_operand:QI 2 "nonimmediate_src_operand" "") + (compare (match_operand:QI 2 "nonimmediate_operand" "") (match_operand:QI 3 "m68k_subword_comparison_operand" ""))) (set (match_operand:QI 0 "register_operand") (match_operator:QI 1 "ordered_comparison_operator" @@ -584,8 +599,8 @@ (define_insn "" [(set (cc0) - (compare (match_operand:QI 0 "nonimmediate_src_operand" "dn,dmS,>") - (match_operand:QI 1 "general_src_operand" "dmS,nd,>")))] + (compare (match_operand:QI 0 "nonimmediate_operand" "dn,dm,>") + (match_operand:QI 1 "general_operand" "dm,nd,>")))] "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) @@ -691,7 +706,7 @@ (minus:SI (const_int 31) (match_operand:SI 1 "general_operand" "di"))) (const_int 0)))] - "" + "!(CONST_INT_P (operands[1]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))" { return output_btst (operands, operands[1], operands[0], insn, 31); }) @@ -750,9 +765,10 @@ (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "do") (const_int 1) - (match_operand:SI 1 "const_int_operand" "n")) + (match_operand:SI 1 "const_int_operand" "n")) (const_int 0)))] - "!TARGET_COLDFIRE" + "!TARGET_COLDFIRE + && !(REG_P (operands[0]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))" { if (GET_CODE (operands[0]) == MEM) { @@ -775,7 +791,8 @@ (const_int 1) (match_operand:SI 1 "const_int_operand" "n")) (const_int 0)))] - "TARGET_COLDFIRE" + "TARGET_COLDFIRE + && !(REG_P (operands[0]) && !IN_RANGE (INTVAL (operands[1]), 0, 31))" { if (GET_CODE (operands[0]) == MEM) { @@ -1119,7 +1136,7 @@ DONE; /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + emit_insn (gen_rtx_SET (operands[0], operands[1])); DONE; }) @@ -1133,7 +1150,7 @@ DONE; /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + emit_insn (gen_rtx_SET (operands[0], operands[1])); DONE; }) @@ -1203,10 +1220,8 @@ { if (which_alternative == 4 || which_alternative == 5) { rtx xoperands[2]; - REAL_VALUE_TYPE r; long l; - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_SINGLE (r, l); + REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); xoperands[0] = operands[0]; xoperands[1] = GEN_INT (l); if (which_alternative == 5) { @@ -1262,7 +1277,7 @@ DONE; /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + emit_insn (gen_rtx_SET (operands[0], operands[1])); DONE; }) @@ -1276,7 +1291,7 @@ DONE; /* We don't want the clobber emitted, so handle this ourselves. */ - emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + emit_insn (gen_rtx_SET (operands[0], operands[1])); DONE; }) @@ -1345,7 +1360,6 @@ "TARGET_COLDFIRE_FPU" { rtx xoperands[3]; - REAL_VALUE_TYPE r; long l[2]; switch (which_alternative) @@ -1361,8 +1375,7 @@ case 4: case 5: case 6: return output_move_double (operands); case 7: - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); + REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); xoperands[0] = operands[0]; xoperands[1] = GEN_INT (l[0]); xoperands[2] = GEN_INT (l[1]); @@ -1383,7 +1396,7 @@ ;; ??? The XFmode patterns are schizophrenic about whether constants are ;; allowed. Most but not all have predicates and constraint that disallow ;; constants. Most but not all have output templates that handle constants. -;; See also LEGITIMATE_CONSTANT_P. +;; See also TARGET_LEGITIMATE_CONSTANT_P. (define_expand "movxf" [(set (match_operand:XF 0 "nonimmediate_operand" "") @@ -1566,7 +1579,7 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d") (truncate:QI (match_operand:SI 1 "general_src_operand" "doJS,i")))] - "" + "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == REG) { @@ -1584,7 +1597,7 @@ [(set (match_operand:QI 0 "nonimmediate_operand" "=dm,d") (truncate:QI (match_operand:HI 1 "general_src_operand" "doJS,i")))] - "" + "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == REG && (GET_CODE (operands[1]) == MEM @@ -1611,7 +1624,7 @@ [(set (match_operand:HI 0 "nonimmediate_operand" "=dm,d") (truncate:HI (match_operand:SI 1 "general_src_operand" "roJS,i")))] - "" + "!TARGET_COLDFIRE" { if (GET_CODE (operands[0]) == REG) { @@ -1862,9 +1875,11 @@ ;; Maybe there is a way to make that the general case, by forcing the ;; result of the SI tree to be in the lower register of the DI target +;; Don't allow memory for operand 1 as that would require an earlyclobber +;; which results in worse code (define_insn "extendplussidi" [(set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn") + (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rn") (match_operand:SI 2 "general_operand" "rmn"))))] "" { @@ -2401,7 +2416,8 @@ if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) { operands[1] = gen_rtx_MEM (SImode, - plus_constant (XEXP(operands[0], 0), -8)); + plus_constant (Pmode, + XEXP(operands[0], 0), -8)); return "move%.l %0,%3\;add%.l %R2,%0\;addx%.l %2,%3\;move%.l %3,%1"; } else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) @@ -2899,7 +2915,8 @@ if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) { operands[1] - = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[0], 0), -8)); + = gen_rtx_MEM (SImode, plus_constant (Pmode, + XEXP (operands[0], 0), -8)); return "move%.l %0,%3\;sub%.l %R2,%0\;subx%.l %2,%3\;move%.l %3,%1"; } else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) @@ -3587,72 +3604,6 @@ ;; logical-and instructions -;; "anddi3" is mainly here to help combine(). -(define_insn "anddi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d") - (and:DI (match_operand:DI 1 "general_operand" "%0,0") - (match_operand:DI 2 "general_operand" "dn,don")))] - "!TARGET_COLDFIRE" -{ - CC_STATUS_INIT; - /* We can get CONST_DOUBLE, but also const1_rtx etc. */ - if (CONSTANT_P (operands[2])) - { - rtx hi, lo; - - split_double (operands[2], &hi, &lo); - - switch (INTVAL (hi)) - { - case 0 : - output_asm_insn ("clr%.l %0", operands); - break; - case -1 : - break; - default : - { - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[2] = hi; - output_asm_insn (output_andsi3 (xoperands), xoperands); - } - } - if (GET_CODE (operands[0]) == REG) - operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else - operands[0] = adjust_address (operands[0], SImode, 4); - switch (INTVAL (lo)) - { - case 0 : - output_asm_insn ("clr%.l %0", operands); - break; - case -1 : - break; - default : - { - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[2] = lo; - output_asm_insn (output_andsi3 (xoperands), xoperands); - } - } - return ""; - } - if (GET_CODE (operands[0]) != REG) - { - operands[1] = adjust_address (operands[0], SImode, 4); - return "and%.l %2,%0\;and%.l %R2,%1"; - } - if (GET_CODE (operands[2]) != REG) - { - operands[1] = adjust_address (operands[2], SImode, 4); - return "and%.l %2,%0\;and%.l %1,%R0"; - } - return "and%.l %2,%0\;and%.l %R2,%R0"; -}) - ;; Prevent AND from being made with sp. This doesn't exist in the machine ;; and reload will cause inefficient code. Since sp is a FIXED_REG, we ;; can't allocate pseudos into it. @@ -3770,76 +3721,6 @@ return "or%.w %1,%0"; }) -;; "iordi3" is mainly here to help combine(). -(define_insn "iordi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d") - (ior:DI (match_operand:DI 1 "general_operand" "%0,0") - (match_operand:DI 2 "general_operand" "dn,don")))] - "!TARGET_COLDFIRE" -{ - CC_STATUS_INIT; - /* We can get CONST_DOUBLE, but also const1_rtx etc. */ - if (CONSTANT_P (operands[2])) - { - rtx hi, lo; - - split_double (operands[2], &hi, &lo); - - switch (INTVAL (hi)) - { - case 0 : - break; - case -1 : - /* FIXME : a scratch register would be welcome here if operand[0] - is not a register */ - output_asm_insn ("move%.l #-1,%0", operands); - break; - default : - { - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[2] = hi; - output_asm_insn (output_iorsi3 (xoperands), xoperands); - } - } - if (GET_CODE (operands[0]) == REG) - operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else - operands[0] = adjust_address (operands[0], SImode, 4); - switch (INTVAL (lo)) - { - case 0 : - break; - case -1 : - /* FIXME : a scratch register would be welcome here if operand[0] - is not a register */ - output_asm_insn ("move%.l #-1,%0", operands); - break; - default : - { - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[2] = lo; - output_asm_insn (output_iorsi3 (xoperands), xoperands); - } - } - return ""; - } - if (GET_CODE (operands[0]) != REG) - { - operands[1] = adjust_address (operands[0], SImode, 4); - return "or%.l %2,%0\;or%.l %R2,%1"; - } - if (GET_CODE (operands[2]) != REG) - { - operands[1] = adjust_address (operands[2], SImode, 4); - return "or%.l %2,%0\;or%.l %1,%R0"; - } - return "or%.l %2,%0\;or%.l %R2,%R0"; -}) - (define_expand "iorsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (ior:SI (match_operand:SI 1 "general_operand" "") @@ -3947,79 +3828,6 @@ ;; xor instructions -;; "xordi3" is mainly here to help combine(). -(define_insn "xordi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=od") - (xor:DI (match_operand:DI 1 "general_operand" "%0") - (match_operand:DI 2 "general_operand" "dn")))] - "!TARGET_COLDFIRE" -{ - CC_STATUS_INIT; - /* We can get CONST_DOUBLE, but also const1_rtx etc. */ - - if (CONSTANT_P (operands[2])) - { - rtx hi, lo; - - split_double (operands[2], &hi, &lo); - - switch (INTVAL (hi)) - { - case 0 : - break; - case -1 : - output_asm_insn ("not%.l %0", operands); - break; - default : - /* FIXME : a scratch register would be welcome here if - -128 <= INTVAL (hi) < -1 */ - { - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[2] = hi; - output_asm_insn (output_xorsi3 (xoperands), xoperands); - } - } - if (GET_CODE (operands[0]) == REG) - operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else - operands[0] = adjust_address (operands[0], SImode, 4); - switch (INTVAL (lo)) - { - case 0 : - break; - case -1 : - output_asm_insn ("not%.l %0", operands); - break; - default : - /* FIXME : a scratch register would be welcome here if - -128 <= INTVAL (lo) < -1 */ - operands[2] = lo; - /* FIXME : this should be merged with xorsi3 */ - { - rtx xoperands[3]; - - xoperands[0] = operands[0]; - xoperands[2] = lo; - output_asm_insn (output_xorsi3 (xoperands), xoperands); - } - } - return ""; - } - if (GET_CODE (operands[0]) != REG) - { - operands[1] = adjust_address (operands[0], SImode, 4); - return "eor%.l %2,%0\;eor%.l %R2,%1"; - } - if (GET_CODE (operands[2]) != REG) - { - operands[1] = adjust_address (operands[2], SImode, 4); - return "eor%.l %2,%0\;eor%.l %1,%R0"; - } - return "eor%.l %2,%0\;eor%.l %R2,%R0"; -}) - (define_expand "xorsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") (xor:SI (match_operand:SI 1 "general_operand" "") @@ -4028,9 +3836,9 @@ "") (define_insn "xorsi3_internal" - [(set (match_operand:SI 0 "nonimmediate_operand" "=do,m") - (xor:SI (match_operand:SI 1 "general_operand" "%0,0") - (match_operand:SI 2 "general_operand" "di,dKT")))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,o,m") + (xor:SI (match_operand:SI 1 "general_operand" "%0, 0,0") + (match_operand:SI 2 "general_operand" "di,dK,dKT")))] "!TARGET_COLDFIRE" { @@ -4457,33 +4265,37 @@ ;; bit indexing instructions +(define_expand "clzsi2" + [(set (match_operand:SI 0 "register_operand" "") + (clz:SI (match_operand:SI 1 "general_operand" "")))] + "ISA_HAS_FF1 || (TARGET_68020 && TARGET_BITFIELD)" +{ + if (ISA_HAS_FF1) + operands[1] = force_reg (SImode, operands[1]); +}) + +(define_insn "*clzsi2_68k" + [(set (match_operand:SI 0 "register_operand" "=d") + (clz:SI (match_operand:SI 1 "general_operand" "do")))] + "TARGET_68020 && TARGET_BITFIELD" +{ + CC_STATUS_INIT; + return "bfffo %1{#0:#0},%0"; +}) + ;; ColdFire ff1 instruction implements clz. -(define_insn "clzsi2" +(define_insn "*clzsi2_cf" [(set (match_operand:SI 0 "register_operand" "=d") (clz:SI (match_operand:SI 1 "register_operand" "0")))] "ISA_HAS_FF1" - "ff1 %0" +{ + CC_STATUS_INIT; + return "ff1 %0"; +} [(set_attr "type" "ext")]) ;; one complement instructions -;; "one_cmpldi2" is mainly here to help combine(). -(define_insn "one_cmpldi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=dm") - (not:DI (match_operand:DI 1 "general_operand" "0")))] - "!TARGET_COLDFIRE" -{ - CC_STATUS_INIT; - if (GET_CODE (operands[0]) == REG) - operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) - operands[1] = operands[0]; - else - operands[1] = adjust_address (operands[0], SImode, 4); - return "not%.l %1\;not%.l %0"; -}) - (define_expand "one_cmplsi2" [(set (match_operand:SI 0 "nonimmediate_operand" "") (not:SI (match_operand:SI 1 "general_operand" "")))] @@ -4535,25 +4347,18 @@ ;; arithmetic shift instructions ;; We don't need the shift memory by 1 bit instruction - -(define_insn "ashldi_extsi" +(define_insn_and_split "ashldi_extsi" [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") (ashift:DI (match_operator:DI 2 "extend_operator" [(match_operand:SI 1 "general_operand" "rm")]) (const_int 32)))] "" -{ - CC_STATUS_INIT; - if (GET_CODE (operands[0]) == REG) - operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - else - operands[2] = adjust_address (operands[0], SImode, 4); - if (ADDRESS_REG_P (operands[0])) - return "move%.l %1,%0\;sub%.l %2,%2"; - else - return "move%.l %1,%0\;clr%.l %2"; -}) + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 2) (const_int 0))] + "split_di(operands, 1, operands + 2, operands + 3);") (define_insn "ashldi_sexthi" [(set (match_operand:DI 0 "nonimmediate_operand" "=m,a*d") @@ -4741,7 +4546,7 @@ (define_expand "ashldi3" [(set (match_operand:DI 0 "register_operand" "") (ashift:DI (match_operand:DI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")))] + (match_operand:SI 2 "const_int_operand" "")))] "!TARGET_COLDFIRE" { /* ??? This is a named pattern like this is not allowed to FAIL based @@ -5010,7 +4815,7 @@ (define_expand "ashrdi3" [(set (match_operand:DI 0 "register_operand" "") (ashiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")))] + (match_operand:SI 2 "const_int_operand" "")))] "!TARGET_COLDFIRE" { /* ??? This is a named pattern like this is not allowed to FAIL based @@ -5279,7 +5084,7 @@ (define_expand "lshrdi3" [(set (match_operand:DI 0 "register_operand" "") (lshiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand 2 "const_int_operand" "")))] + (match_operand:SI 2 "const_int_operand" "")))] "!TARGET_COLDFIRE" { /* ??? This is a named pattern like this is not allowed to FAIL based @@ -5408,19 +5213,19 @@ return "rol%.w %2,%0"; }) -(define_insn "" +(define_insn "*rotlhi3_lowpart" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) (rotate:HI (match_dup 0) (match_operand:HI 1 "general_operand" "dIP")))] "!TARGET_COLDFIRE" { - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 8) + if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= 8) { - operands[2] = GEN_INT (16 - INTVAL (operands[2])); - return "ror%.w %2,%0"; + operands[1] = GEN_INT (16 - INTVAL (operands[1])); + return "ror%.w %1,%0"; } else - return "rol%.w %2,%0"; + return "rol%.w %1,%0"; }) (define_insn "rotlqi3" @@ -5438,19 +5243,19 @@ return "rol%.b %2,%0"; }) -(define_insn "" +(define_insn "*rotlqi3_lowpart" [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d")) (rotate:QI (match_dup 0) (match_operand:QI 1 "general_operand" "dI")))] "!TARGET_COLDFIRE" { - if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 4) + if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) >= 4) { - operands[2] = GEN_INT (8 - INTVAL (operands[2])); - return "ror%.b %2,%0"; + operands[1] = GEN_INT (8 - INTVAL (operands[1])); + return "ror%.b %1,%0"; } else - return "rol%.b %2,%0"; + return "rol%.b %1,%0"; }) (define_insn "rotrsi3" @@ -5467,7 +5272,7 @@ "!TARGET_COLDFIRE" "ror%.w %2,%0") -(define_insn "" +(define_insn "rotrhi_lowpart" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d")) (rotatert:HI (match_dup 0) (match_operand:HI 1 "general_operand" "dI")))] @@ -5487,6 +5292,19 @@ (match_operand:QI 1 "general_operand" "dI")))] "!TARGET_COLDFIRE" "ror%.b %1,%0") + +(define_expand "bswapsi2" + [(set (match_operand:SI 0 "register_operand") + (bswap:SI (match_operand:SI 1 "register_operand")))] + "!TARGET_COLDFIRE" +{ + rtx x = operands[0]; + emit_move_insn (x, operands[1]); + emit_insn (gen_rotrhi_lowpart (gen_lowpart (HImode, x), GEN_INT (8))); + emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); + emit_insn (gen_rotrhi_lowpart (gen_lowpart (HImode, x), GEN_INT (8))); + DONE; +}) ;; Bit set/clear in memory byte. @@ -5518,6 +5336,45 @@ } [(set_attr "type" "bitrw")]) +(define_insn "*bsetdreg" + [(set (match_operand:SI 0 "register_operand" "=d") + (ior:SI (ashift:SI (const_int 1) + (and:SI (match_operand:SI 1 "register_operand" "d") + (const_int 31))) + (match_operand:SI 2 "register_operand" "0")))] + "" +{ + CC_STATUS_INIT; + return "bset %1,%0"; +} + [(set_attr "type" "bitrw")]) + +(define_insn "*bchgdreg" + [(set (match_operand:SI 0 "register_operand" "=d") + (xor:SI (ashift:SI (const_int 1) + (and:SI (match_operand:SI 1 "register_operand" "d") + (const_int 31))) + (match_operand:SI 2 "register_operand" "0")))] + "" +{ + CC_STATUS_INIT; + return "bchg %1,%0"; +} + [(set_attr "type" "bitrw")]) + +(define_insn "*bclrdreg" + [(set (match_operand:SI 0 "register_operand" "=d") + (and:SI (rotate:SI (const_int -2) + (and:SI (match_operand:SI 1 "register_operand" "d") + (const_int 31))) + (match_operand:SI 2 "register_operand" "0")))] + "" +{ + CC_STATUS_INIT; + return "bclr %1,%0"; +} + [(set_attr "type" "bitrw")]) + ;; clear bit, bit number is int (define_insn "bclrmemqi" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m") @@ -5559,14 +5416,15 @@ ; The move is allowed to be odd byte aligned, because that's still faster ; than an odd byte aligned bit-field instruction. ; -(define_insn "" +(define_insn "*insv_32_mem" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") (const_int 32) (match_operand:SI 1 "const_int_operand" "n")) (match_operand:SI 2 "general_src_operand" "rmSi"))] "TARGET_68020 && TARGET_BITFIELD && (INTVAL (operands[1]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[0], 0))" + && ! mode_dependent_address_p (XEXP (operands[0], 0), + MEM_ADDR_SPACE (operands[0]))" { operands[0] = adjust_address (operands[0], SImode, INTVAL (operands[1]) / 8); @@ -5574,31 +5432,18 @@ return "move%.l %2,%0"; }) -(define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+do") +(define_insn "*insv_8_16_reg" + [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (match_operand:SI 3 "register_operand" "d"))] "TARGET_68020 && TARGET_BITFIELD + && IN_RANGE (INTVAL (operands[2]), 0, 31) && (INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16) - && INTVAL (operands[2]) % INTVAL (operands[1]) == 0 - && (GET_CODE (operands[0]) == REG - || ! mode_dependent_address_p (XEXP (operands[0], 0)))" -{ - if (REG_P (operands[0])) - { - if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) - return "bfins %3,%0{%b2:%b1}"; - } - else - operands[0] = adjust_address (operands[0], - INTVAL (operands[1]) == 8 ? QImode : HImode, - INTVAL (operands[2]) / 8); - - if (GET_CODE (operands[3]) == MEM) - operands[3] = adjust_address (operands[3], - INTVAL (operands[1]) == 8 ? QImode : HImode, - (32 - INTVAL (operands[1])) / 8); + && INTVAL (operands[2]) % INTVAL (operands[1]) == 0" +{ + if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32) + return "bfins %3,%0{%b2:%b1}"; if (INTVAL (operands[1]) == 8) return "move%.b %3,%0"; @@ -5613,14 +5458,15 @@ ; The move is allowed to be odd byte aligned, because that's still faster ; than an odd byte aligned bit-field instruction. ; -(define_insn "" +(define_insn "*extzv_32_mem" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (zero_extract:SI (match_operand:QI 1 "memory_src_operand" "oS") (const_int 32) (match_operand:SI 2 "const_int_operand" "n")))] "TARGET_68020 && TARGET_BITFIELD && (INTVAL (operands[2]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[1], 0))" + && ! mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1]))" { operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8); @@ -5628,33 +5474,21 @@ return "move%.l %1,%0"; }) -(define_insn "" +(define_insn "*extzv_8_16_reg" [(set (match_operand:SI 0 "nonimmediate_operand" "=&d") - (zero_extract:SI (match_operand:SI 1 "register_operand" "do") + (zero_extract:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] "TARGET_68020 && TARGET_BITFIELD + && IN_RANGE (INTVAL (operands[3]), 0, 31) && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))" + && INTVAL (operands[3]) % INTVAL (operands[2]) == 0" { cc_status.flags |= CC_NOT_NEGATIVE; - if (REG_P (operands[1])) - { - if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) - return "bfextu %1{%b3:%b2},%0"; - } - else - operands[1] - = adjust_address (operands[1], SImode, INTVAL (operands[3]) / 8); + if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) + return "bfextu %1{%b3:%b2},%0"; output_asm_insn ("clr%.l %0", operands); - if (GET_CODE (operands[0]) == MEM) - operands[0] = adjust_address (operands[0], - INTVAL (operands[2]) == 8 ? QImode : HImode, - (32 - INTVAL (operands[1])) / 8); - if (INTVAL (operands[2]) == 8) return "move%.b %1,%0"; return "move%.w %1,%0"; @@ -5667,14 +5501,15 @@ ; The move is allowed to be odd byte aligned, because that's still faster ; than an odd byte aligned bit-field instruction. ; -(define_insn "" +(define_insn "*extv_32_mem" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (sign_extract:SI (match_operand:QI 1 "memory_src_operand" "oS") (const_int 32) (match_operand:SI 2 "const_int_operand" "n")))] "TARGET_68020 && TARGET_BITFIELD && (INTVAL (operands[2]) % 8) == 0 - && ! mode_dependent_address_p (XEXP (operands[1], 0))" + && ! mode_dependent_address_p (XEXP (operands[1], 0), + MEM_ADDR_SPACE (operands[1]))" { operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) / 8); @@ -5682,27 +5517,18 @@ return "move%.l %1,%0"; }) -(define_insn "" +(define_insn "*extv_8_16_reg" [(set (match_operand:SI 0 "nonimmediate_operand" "=d") - (sign_extract:SI (match_operand:SI 1 "register_operand" "do") + (sign_extract:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] "TARGET_68020 && TARGET_BITFIELD + && IN_RANGE (INTVAL (operands[3]), 0, 31) && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) - && INTVAL (operands[3]) % INTVAL (operands[2]) == 0 - && (GET_CODE (operands[1]) == REG - || ! mode_dependent_address_p (XEXP (operands[1], 0)))" -{ - if (REG_P (operands[1])) - { - if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) - return "bfexts %1{%b3:%b2},%0"; - } - else - operands[1] - = adjust_address (operands[1], - INTVAL (operands[2]) == 8 ? QImode : HImode, - INTVAL (operands[3]) / 8); + && INTVAL (operands[3]) % INTVAL (operands[2]) == 0" +{ + if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32) + return "bfexts %1{%b3:%b2},%0"; if (INTVAL (operands[2]) == 8) return "move%.b %1,%0\;extb%.l %0"; @@ -5721,7 +5547,7 @@ "TARGET_68020 && TARGET_BITFIELD" "") -(define_insn "" +(define_insn "*extv_bfexts_mem" [(set (match_operand:SI 0 "register_operand" "=d") (sign_extract:SI (match_operand:QI 1 "memory_operand" "o") (match_operand:SI 2 "nonmemory_operand" "dn") @@ -5737,7 +5563,7 @@ "TARGET_68020 && TARGET_BITFIELD" "") -(define_insn "" +(define_insn "*extzv_bfextu_mem" [(set (match_operand:SI 0 "register_operand" "=d") (zero_extract:SI (match_operand:QI 1 "memory_operand" "o") (match_operand:SI 2 "nonmemory_operand" "dn") @@ -5756,7 +5582,7 @@ return "bfextu %1{%b3:%b2},%0"; }) -(define_insn "" +(define_insn "*insv_bfchg_mem" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") (match_operand:SI 1 "nonmemory_operand" "dn") (match_operand:SI 2 "nonmemory_operand" "dn")) @@ -5771,7 +5597,7 @@ return "bfchg %0{%b2:%b1}"; }) -(define_insn "" +(define_insn "*insv_bfclr_mem" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") (match_operand:SI 1 "nonmemory_operand" "dn") (match_operand:SI 2 "nonmemory_operand" "dn")) @@ -5782,7 +5608,7 @@ return "bfclr %0{%b2:%b1}"; }) -(define_insn "" +(define_insn "*insv_bfset_mem" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") (match_operand:SI 1 "general_operand" "dn") (match_operand:SI 2 "general_operand" "dn")) @@ -5797,11 +5623,22 @@ [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "") (match_operand:SI 1 "const_int_operand" "") (match_operand:SI 2 "const_int_operand" "")) - (match_operand:SI 3 "register_operand" ""))] + (match_operand:SI 3 "reg_or_pow2_m1_operand" ""))] "TARGET_68020 && TARGET_BITFIELD" - "") - -(define_insn "" + " +{ + /* Special case initializing a field to all ones. */ + if (GET_CODE (operands[3]) == CONST_INT) + { + if (exact_log2 (INTVAL (operands[3]) + 1) != INTVAL (operands[1])) + operands[3] = force_reg (SImode, operands[3]); + else + operands[3] = constm1_rtx; + + } +}") + +(define_insn "*insv_bfins_mem" [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o") (match_operand:SI 1 "nonmemory_operand" "dn") (match_operand:SI 2 "nonmemory_operand" "dn")) @@ -5812,20 +5649,20 @@ ;; Now recognize bit-field insns that operate on registers ;; (or at least were intended to do so). -(define_insn "" +(define_insn "*extv_bfexts_reg" [(set (match_operand:SI 0 "nonimmediate_operand" "=d") (sign_extract:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] - "TARGET_68020 && TARGET_BITFIELD" + "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)" "bfexts %1{%b3:%b2},%0") -(define_insn "" +(define_insn "*extv_bfextu_reg" [(set (match_operand:SI 0 "nonimmediate_operand" "=d") (zero_extract:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "const_int_operand" "n") (match_operand:SI 3 "const_int_operand" "n")))] - "TARGET_68020 && TARGET_BITFIELD" + "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[3]), 0, 31)" { if (GET_CODE (operands[2]) == CONST_INT) { @@ -5839,34 +5676,34 @@ return "bfextu %1{%b3:%b2},%0"; }) -(define_insn "" +(define_insn "*insv_bfclr_reg" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (const_int 0))] - "TARGET_68020 && TARGET_BITFIELD" + "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" { CC_STATUS_INIT; return "bfclr %0{%b2:%b1}"; }) -(define_insn "" +(define_insn "*insv_bfset_reg" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (const_int -1))] - "TARGET_68020 && TARGET_BITFIELD" + "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" { CC_STATUS_INIT; return "bfset %0{%b2:%b1}"; }) -(define_insn "" +(define_insn "*insv_bfins_reg" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+d") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")) (match_operand:SI 3 "register_operand" "d"))] - "TARGET_68020 && TARGET_BITFIELD" + "TARGET_68020 && TARGET_BITFIELD && IN_RANGE (INTVAL (operands[2]), 0, 31)" { #if 0 /* These special cases are now recognized by a specific pattern. */ @@ -5882,7 +5719,7 @@ ;; Special patterns for optimizing bit-field instructions. -(define_insn "" +(define_insn "*tst_bftst_mem" [(set (cc0) (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "o") (match_operand:SI 1 "const_int_operand" "n") @@ -5908,13 +5745,14 @@ ;;; now handle the register cases -(define_insn "" +(define_insn "*tst_bftst_reg" [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "general_operand" "dn")) (const_int 0)))] - "TARGET_68020 && TARGET_BITFIELD" + "TARGET_68020 && TARGET_BITFIELD + && !(CONST_INT_P (operands[2]) && !IN_RANGE (INTVAL (operands[2]), 0, 31))" { if (operands[1] == const1_rtx && GET_CODE (operands[2]) == CONST_INT) @@ -6177,15 +6015,15 @@ (define_insn "beq0_di" [(set (pc) - (if_then_else (eq (match_operand:DI 0 "general_operand" "d*ao,<>") + (if_then_else (eq (match_operand:DI 0 "general_operand" "d*a,o,<>") (const_int 0)) - (label_ref (match_operand 1 "" ",")) + (label_ref (match_operand 1 "" ",,")) (pc))) - (clobber (match_scratch:SI 2 "=d,d"))] + (clobber (match_scratch:SI 2 "=d,&d,d"))] "" { CC_STATUS_INIT; - if (which_alternative == 1) + if (which_alternative == 2) return "move%.l %0,%2\;or%.l %0,%2\;jeq %l1"; if ((cc_prev_status.value1 && rtx_equal_p (cc_prev_status.value1, operands[0])) @@ -6222,11 +6060,11 @@ (define_insn "bne0_di" [(set (pc) - (if_then_else (ne (match_operand:DI 0 "general_operand" "do,*a") + (if_then_else (ne (match_operand:DI 0 "general_operand" "d,o,*a") (const_int 0)) - (label_ref (match_operand 1 "" ",")) + (label_ref (match_operand 1 "" ",,")) (pc))) - (clobber (match_scratch:SI 2 "=d,X"))] + (clobber (match_scratch:SI 2 "=d,&d,X"))] "" { if ((cc_prev_status.value1 @@ -6323,7 +6161,7 @@ { OUTPUT_JUMP ("jeq %l0", "fjeq %l0", "jeq %l0"); } - [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) + [(set_attr "type" "bcc")]) (define_insn "bne" [(set (pc) @@ -6335,7 +6173,7 @@ { OUTPUT_JUMP ("jne %l0", "fjne %l0", "jne %l0"); } - [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) + [(set_attr "type" "bcc")]) (define_insn "bgt" [(set (pc) @@ -6353,7 +6191,7 @@ OUTPUT_JUMP ("jgt %l0", "fjgt %l0", 0); } - [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) + [(set_attr "type" "bcc")]) (define_insn "bgtu" [(set (pc) @@ -6389,7 +6227,7 @@ OUTPUT_JUMP ("jlt %l0", "fjlt %l0", "jmi %l0"); } - [(set (attr "type") (symbol_ref "m68k_sched_branch_type (insn)"))]) + [(set_attr "type" "bcc")]) (define_insn "bltu" [(set (pc) @@ -6855,9 +6693,11 @@ (use (label_ref (match_operand 1 "" "")))])] "" { -#ifdef CASE_VECTOR_PC_RELATIVE +#if CASE_VECTOR_PC_RELATIVE operands[0] = gen_rtx_PLUS (SImode, pc_rtx, - gen_rtx_SIGN_EXTEND (SImode, operands[0])); + TARGET_LONG_JUMP_TABLE_OFFSETS + ? operands[0] + : gen_rtx_SIGN_EXTEND (SImode, operands[0])); #endif }) @@ -6872,12 +6712,26 @@ [(set_attr "type" "jmp")]) ;; Jump to variable address from dispatch table of relative addresses. -(define_insn "" +(define_insn "*tablejump_pcrel_si" + [(set (pc) + (plus:SI (pc) + (match_operand:SI 0 "register_operand" "r"))) + (use (label_ref (match_operand 1 "" "")))] + "TARGET_LONG_JUMP_TABLE_OFFSETS" +{ +#ifdef ASM_RETURN_CASE_JUMP + ASM_RETURN_CASE_JUMP; +#else + return MOTOROLA ? "jmp (2,pc,%0.l)" : "jmp pc@(2,%0:l)"; +#endif +}) + +(define_insn "*tablejump_pcrel_hi" [(set (pc) (plus:SI (pc) (sign_extend:SI (match_operand:HI 0 "register_operand" "r")))) (use (label_ref (match_operand 1 "" "")))] - "" + "!TARGET_LONG_JUMP_TABLE_OFFSETS" { #ifdef ASM_RETURN_CASE_JUMP ASM_RETURN_CASE_JUMP; @@ -7111,7 +6965,7 @@ { int i; - emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); + emit_call_insn (gen_call (operands[0], const0_rtx)); for (i = 0; i < XVECLEN (operands[2], 0); i++) { @@ -7243,7 +7097,8 @@ (match_operand:SI 1 "const_int_operand")))])] "TARGET_68020 || INTVAL (operands[1]) >= -0x8004" { - operands[2] = gen_frame_mem (SImode, plus_constant (stack_pointer_rtx, -4)); + operands[2] = gen_frame_mem (SImode, + plus_constant (Pmode, stack_pointer_rtx, -4)); }) (define_insn "*link" @@ -7806,3 +7661,182 @@ [(set_attr "type" "ib")]) (include "cf.md") +(include "sync.md") + +;; Convert +;; +;; move.l 4(%a0),%a0 +;; clr.b (%a0,%a1.l) +;; +;; into +;; +;; add.l 4(%a0),%a1 +;; clr.b (%a1) +;; +;; The latter is smaller. It is faster on all models except m68060. + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "const_int_operand" "")))) + (set (mem:QI (plus:SI (match_operand:SI 3 "register_operand" "") + (match_operand:SI 4 "register_operand" ""))) + (const_int 0))] + "(optimize_size || !TUNE_68060) + && (operands[0] == operands[3] || operands[0] == operands[4]) + && ADDRESS_REG_P (operands[1]) + && ADDRESS_REG_P ((operands[0] == operands[3]) ? operands[4] : operands[3]) + && peep2_reg_dead_p (2, operands[3]) + && peep2_reg_dead_p (2, operands[4])" + [(set (match_dup 5) + (plus:SI (match_dup 5) + (mem:SI (plus:SI (match_dup 1) + (match_dup 2))))) + (set (mem:QI (match_dup 5)) + (const_int 0))] + "operands[5] = (operands[0] == operands[3]) ? operands[4] : operands[3];") + +;; We want to turn +;; moveq const,dX +;; cmp.l dX,dY +;; je/jne +;; +;; into +;; addq/subq -const,dY +;; cmp.l dY, 0 +;; je/jne +;; +;; dX and dY must both be dead at the end of the sequence and the constant +;; must be valid for addq/subq. +;; +;; Essentially we're making it trivial for final to realize the comparison +;; is not needed +;; +;; Testing has shown a variant where the operands are reversed in the +;; comparison never hits, so I have not included that variant. +;; + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "addq_subq_operand" "")) + (set (cc0) (compare (match_operand:SI 2 "register_operand" "") + (match_dup 0))) + (set (pc) (if_then_else (match_operator 5 "equality_comparison_operator" + [(cc0) (const_int 0)]) + (match_operand 3 "pc_or_label_operand") + (match_operand 4 "pc_or_label_operand")))] + "peep2_reg_dead_p (2, operands[0]) + && peep2_reg_dead_p (2, operands[2]) + && (operands[3] == pc_rtx || operands[4] == pc_rtx) + && DATA_REG_P (operands[2]) + && !rtx_equal_p (operands[0], operands[2])" + [(set (match_dup 2) (plus:SI (match_dup 2) (match_dup 6))) + (set (cc0) (compare (match_dup 2) (const_int 0))) + (set (pc) (if_then_else (match_op_dup 5 [(cc0) (const_int 0)]) + (match_dup 3) + (match_dup 4)))] + "operands[6] = GEN_INT (-INTVAL (operands[1]));") + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "pow2_m1_operand" "")) + (set (cc0) (compare (match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "register_operand" ""))) + (set (pc) (if_then_else (gtu (cc0) (const_int 0)) + (match_operand 4 "pc_or_label_operand") + (match_operand 5 "pc_or_label_operand")))] + "INTVAL (operands[1]) <= 255 + && operands[0] == operands[3] + && peep2_reg_dead_p (2, operands[0]) + && peep2_reg_dead_p (2, operands[2]) + && (operands[4] == pc_rtx || operands[5] == pc_rtx) + && (optimize_size || TUNE_68040_60) + && DATA_REG_P (operands[2])" + [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6))) + (set (cc0) (compare (match_dup 7) (const_int 0))) + (set (pc) (if_then_else (ne (cc0) (const_int 0)) + (match_dup 4) (match_dup 5)))] + " +{ + operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); + operands[7] = operands[2]; +}") + +(define_peephole2 + [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "pow2_m1_operand" ""))) + (set (pc) (if_then_else (gtu (cc0) (const_int 0)) + (match_operand 2 "pc_or_label_operand") + (match_operand 3 "pc_or_label_operand")))] + "INTVAL (operands[1]) <= 255 + && peep2_reg_dead_p (1, operands[0]) + && (operands[2] == pc_rtx || operands[3] == pc_rtx) + && (optimize_size || TUNE_68040_60) + && DATA_REG_P (operands[0])" + [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4))) + (set (cc0) (compare (match_dup 0) (const_int 0))) + (set (pc) (if_then_else (ne (cc0) (const_int 0)) + (match_dup 2) (match_dup 3)))] + "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }") + +(define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "pow2_m1_operand" "")) + (set (cc0) (compare (match_operand:SI 2 "register_operand" "") + (match_operand:SI 3 "register_operand" ""))) + (set (pc) (if_then_else (leu (cc0) (const_int 0)) + (match_operand 4 "pc_or_label_operand") + (match_operand 5 "pc_or_label_operand")))] + "INTVAL (operands[1]) <= 255 + && operands[0] == operands[3] + && peep2_reg_dead_p (2, operands[0]) + && peep2_reg_dead_p (2, operands[2]) + && (operands[4] == pc_rtx || operands[5] == pc_rtx) + && (optimize_size || TUNE_68040_60) + && DATA_REG_P (operands[2])" + [(set (match_dup 7) (lshiftrt:SI (match_dup 7) (match_dup 6))) + (set (cc0) (compare (match_dup 7) (const_int 0))) + (set (pc) (if_then_else (eq (cc0) (const_int 0)) + (match_dup 4) (match_dup 5)))] + " +{ + operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); + operands[7] = operands[2]; +}") +(define_peephole2 + [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "pow2_m1_operand" ""))) + (set (pc) (if_then_else (leu (cc0) (const_int 0)) + (match_operand 2 "pc_or_label_operand") + (match_operand 3 "pc_or_label_operand")))] + "INTVAL (operands[1]) <= 255 + && peep2_reg_dead_p (1, operands[0]) + && (operands[2] == pc_rtx || operands[3] == pc_rtx) + && (optimize_size || TUNE_68040_60) + && DATA_REG_P (operands[0])" + [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 4))) + (set (cc0) (compare (match_dup 0) (const_int 0))) + (set (pc) (if_then_else (eq (cc0) (const_int 0)) + (match_dup 2) (match_dup 3)))] + "{ operands[4] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1)); }") + +;; When optimizing for size or for the original 68000 or 68010, we can +;; improve some relational tests against 65536 (which get canonicalized +;; internally against 65535). +;; The rotate in the output pattern will turn into a swap. +(define_peephole2 + [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") + (const_int 65535))) + (set (pc) (if_then_else (match_operator 1 "swap_peephole_relational_operator" + [(cc0) (const_int 0)]) + (match_operand 2 "pc_or_label_operand") + (match_operand 3 "pc_or_label_operand")))] + "peep2_reg_dead_p (1, operands[0]) + && (operands[2] == pc_rtx || operands[3] == pc_rtx) + && (optimize_size || TUNE_68000_10) + && DATA_REG_P (operands[0])" + [(set (match_dup 0) (rotate:SI (match_dup 0) (const_int 16))) + (set (cc0) (compare (subreg:HI (match_dup 0) 2) (const_int 0))) + (set (pc) (if_then_else (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 2) (match_dup 3)))] + "")