From 5f24901c296f7f44acddd2f4ea0556ef9df55bf5 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Mon, 14 Jul 1997 07:41:09 -0400 Subject: [PATCH] (adddi3, subdi3): Allow constant operand. (anddi3, iordi3, xordi3): New patterns. ({and,ior,xor}si3_internal): Use corresponding output_???si3 function. From-SVN: r14430 --- gcc/config/m68k/m68k.md | 357 ++++++++++++++++++++++++++++++---------- 1 file changed, 271 insertions(+), 86 deletions(-) diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index dec5ff67153..40e59a0532a 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -2039,7 +2039,7 @@ (define_insn "adddi3" [(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d") (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0,0") - (match_operand:DI 2 "general_operand" "<,d,o>,d,a"))) + (match_operand:DI 2 "general_operand" "<,d,no>,d,a"))) (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))] "" "* @@ -2055,11 +2055,21 @@ } else { - /* TODO : this should work also for CONST operands[2] */ if (GET_CODE (operands[2]) == REG) operands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1); + else if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); + operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[2])); + } + else if (GET_CODE (operands[2]) == CONST_INT) + { + operands[1] = operands[2]; + operands[2] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx; + } else operands[1] = adj_offsettable_operand (operands[2], 4); + /* TODO : for consts, optimize move and add */ return \"move%.l %2,%3\;add%.l %1,%R0\;addx%.l %3,%0\"; } } @@ -2573,7 +2583,7 @@ (define_insn "subdi3" [(set (match_operand:DI 0 "general_operand" "=<,o<>,d,d,d") (minus:DI (match_operand:DI 1 "general_operand" "0,0,0,0,0") - (match_operand:DI 2 "general_operand" "<,d,o>,d,a"))) + (match_operand:DI 2 "general_operand" "<,d,no>,d,a"))) (clobber (match_scratch:SI 3 "=X,&d,&d,X,&d"))] "" "* @@ -2589,11 +2599,21 @@ } else { - /* TODO : this should work also for CONST operands[2] */ if (GET_CODE (operands[2]) == REG) operands[1] = gen_rtx (REG, SImode, REGNO (operands[2]) + 1); + else if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); + operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[2])); + } + else if (GET_CODE (operands[2]) == CONST_INT) + { + operands[1] = operands[2]; + operands[2] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx; + } else operands[1] = adj_offsettable_operand (operands[2], 4); + /* TODO : for consts, optimize move and sub */ return \"move%.l %2,%3\;sub%.l %1,%R0\;subx%.l %3,%0\"; } } @@ -3378,9 +3398,9 @@ "* { #ifdef MOTOROLA - output_asm_insn(\"ext%.l %0\;divs%.w %2,%0\", operands); + output_asm_insn (\"ext%.l %0\;divs%.w %2,%0\", operands); #else - output_asm_insn(\"extl %0\;divs %2,%0\", operands); + output_asm_insn (\"extl %0\;divs %2,%0\", operands); #endif if (!find_reg_note(insn, REG_UNUSED, operands[3])) { @@ -3401,9 +3421,9 @@ "* { #ifdef MOTOROLA - output_asm_insn(\"and%.l %#0xFFFF,%0\;divu%.w %2,%0\", operands); + output_asm_insn (\"and%.l %#0xFFFF,%0\;divu%.w %2,%0\", operands); #else - output_asm_insn(\"and%.l %#0xFFFF,%0\;divu %2,%0\", operands); + output_asm_insn (\"and%.l %#0xFFFF,%0\;divu %2,%0\", operands); #endif if (!find_reg_note(insn, REG_UNUSED, operands[3])) { @@ -3416,6 +3436,82 @@ ;; logical-and instructions +;; "anddi3" is mainly here to help combine(). +(define_insn "anddi3" + [(set (match_operand:DI 0 "general_operand" "=o,d") + (and:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "dn,don")))] + "" + "* +{ + CC_STATUS_INIT; + /* We can get CONST_DOUBLE, but also const1_rtx etc. */ + if (GET_CODE (operands[2]) == CONST_DOUBLE + || GET_CODE (operands[2]) == CONST_INT) + { + rtx hi, lo; + + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + hi = GEN_INT (CONST_DOUBLE_HIGH (operands[2])); + lo = GEN_INT (CONST_DOUBLE_LOW (operands[2])); + } + else + { + lo = operands[2]; + hi = INTVAL (lo) < 0 ? constm1_rtx : const0_rtx; + } + 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] = adj_offsettable_operand (operands[0], 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] = adj_offsettable_operand (operands[0], 4); + return \"and%.l %2,%0\;and%.l %R2,%1\"; + } + if (GET_CODE (operands[2]) != REG) + { + operands[1] = adj_offsettable_operand (operands[2], 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. @@ -3434,41 +3530,7 @@ "!TARGET_5200" "* { - int logval; - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) | 0xffff) == 0xffffffff - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (GET_CODE (operands[0]) != REG) - operands[0] = adj_offsettable_operand (operands[0], 2); - operands[2] = gen_rtx (CONST_INT, VOIDmode, - INTVAL (operands[2]) & 0xffff); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - if (operands[2] == const0_rtx) - return \"clr%.w %0\"; - return \"and%.w %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT - && (logval = exact_log2 (~ INTVAL (operands[2]))) >= 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); - } - else - { - operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); - } - /* This does not set condition codes in a standard way. */ - CC_STATUS_INIT; - return \"bclr %1,%0\"; - } - return \"and%.l %2,%0\"; + return output_andsi3 (operands); }") (define_insn "andsi3_5200" @@ -3522,6 +3584,86 @@ ;; inclusive-or instructions +;; "iordi3" is mainly here to help combine(). +(define_insn "iordi3" + [(set (match_operand:DI 0 "general_operand" "=o,d") + (ior:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "dn,don")))] + "!TARGET_5200" + "* +{ + CC_STATUS_INIT; + /* We can get CONST_DOUBLE, but also const1_rtx etc. */ + if (GET_CODE (operands[2]) == CONST_DOUBLE + || GET_CODE (operands[2]) == CONST_INT) + { + rtx hi, lo; + + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + hi = GEN_INT (CONST_DOUBLE_HIGH (operands[2])); + lo = GEN_INT (CONST_DOUBLE_LOW (operands[2])); + } + else + { + lo = operands[2]; + hi = INTVAL (lo) < 0 ? constm1_rtx : const0_rtx; + } + 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] = adj_offsettable_operand (operands[0], 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,%R0\", 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] = adj_offsettable_operand (operands[0], 4); + return \"or%.l %2,%0\;or%.l %R2,%1\"; + } + if (GET_CODE (operands[2]) != REG) + { + operands[1] = adj_offsettable_operand (operands[2], 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 "general_operand" "") (ior:SI (match_operand:SI 1 "general_operand" "") @@ -3533,39 +3675,10 @@ [(set (match_operand:SI 0 "general_operand" "=m,d") (ior:SI (match_operand:SI 1 "general_operand" "%0,0") (match_operand:SI 2 "general_operand" "dKs,dmMs")))] - "!TARGET_5200" + "" "* { - register int logval; - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >> 16 == 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (GET_CODE (operands[0]) != REG) - operands[0] = adj_offsettable_operand (operands[0], 2); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - return \"or%.w %2,%0\"; - } - if (GET_CODE (operands[2]) == CONST_INT - && (logval = exact_log2 (INTVAL (operands[2]))) >= 0 - && (DATA_REG_P (operands[0]) - || offsettable_memref_p (operands[0]))) - { - if (DATA_REG_P (operands[0])) - { - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval); - } - else - { - operands[0] = adj_offsettable_operand (operands[0], 3 - (logval / 8)); - operands[1] = gen_rtx (CONST_INT, VOIDmode, logval % 8); - } - CC_STATUS_INIT; - return \"bset %1,%0\"; - } - return \"or%.l %2,%0\"; + return output_iorsi3 (operands); }") (define_insn "iorsi3_5200" @@ -3658,6 +3771,88 @@ ;; xor instructions +;; "xordi3" is mainly here to help combine(). +(define_insn "xordi3" + [(set (match_operand:DI 0 "general_operand" "=od") + (xor:DI (match_operand:DI 1 "general_operand" "%0") + (match_operand:DI 2 "general_operand" "dn")))] + "" + "* +{ + CC_STATUS_INIT; + /* We can get CONST_DOUBLE, but also const1_rtx etc. */ + if (GET_CODE (operands[2]) == CONST_DOUBLE + || GET_CODE (operands[2]) == CONST_INT) + { + rtx hi, lo; + + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + hi = GEN_INT (CONST_DOUBLE_HIGH (operands[2])); + lo = GEN_INT (CONST_DOUBLE_LOW (operands[2])); + } + else + { + lo = operands[2]; + hi = INTVAL (lo) < 0 ? constm1_rtx : const0_rtx; + } + 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] = adj_offsettable_operand (operands[0], 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] = adj_offsettable_operand (operands[0], 4); + return \"eor%.l %2,%0\;eor%.l %R2,%1\"; + } + if (GET_CODE (operands[2]) != REG) + { + operands[1] = adj_offsettable_operand (operands[2], 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 "general_operand" "") (xor:SI (match_operand:SI 1 "general_operand" "") @@ -3672,17 +3867,7 @@ "!TARGET_5200" "* { - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) >> 16 == 0 - && (offsettable_memref_p (operands[0]) || DATA_REG_P (operands[0]))) - { - if (! DATA_REG_P (operands[0])) - operands[0] = adj_offsettable_operand (operands[0], 2); - /* Do not delete a following tstl %0 insn; that would be incorrect. */ - CC_STATUS_INIT; - return \"eor%.w %2,%0\"; - } - return \"eor%.l %2,%0\"; + return output_xorsi3 (operands); }") (define_insn "xorsi3_5200" @@ -4059,7 +4244,7 @@ ;; one complement instructions -;; "one_cmpldi2" is only here to help combine(). +;; "one_cmpldi2" is mainly here to help combine(). (define_insn "one_cmpldi2" [(set (match_operand:DI 0 "general_operand" "=dm") (not:DI (match_operand:DI 1 "general_operand" "0")))] -- 2.30.2