From 953b10d0d745a971c83cf953da5ed903ecbe776b Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 16 Apr 1996 16:08:32 -0600 Subject: [PATCH] h8300.md (andhi3): If 2nd operand is a CONST_INT that meets the 'J' constraint... * h8300/h8300.md (andhi3): If 2nd operand is a CONST_INT that meets the 'J' constraint, then only two bytes are needed for this insn. Improve code generated for the h8300h when both operands are registers. (iorhi3, xorhi3): Likewise. Rework to be nearly identical to andhi3. (andsi3): If 2nd operand is a CONST_INT that meets the 'J' constraint, then only two bytes are need for this insn. Improve code generated for the h8300h regardless of the type of the 2nd operand. Make this pattern work on the h8300 too. (iorsi3, xorsi3): Likewise. Rework to be nearly identical to andsi3. (iorqi3_internal): Make this pattern look more like andqi3_internal. (one_cmplhi2, one_cmplsi2): Fix length computation for H8300H. From-SVN: r11830 --- gcc/config/h8300/h8300.md | 249 ++++++++++++++++++++++++-------------- 1 file changed, 155 insertions(+), 94 deletions(-) diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 282710efedc1..4c8f512d2d9f 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -48,6 +48,11 @@ ;; would be more efficient time and space-wise. Similar sequences ;; can be found using bit-set insns dec, etc +;; Many logical operations should have "bit" variants if only one +;; bit is going to be operated on. + +;; Should be HI & SImode tstXX insns which test one bit using btst. + (define_attr "type" "branch,bcs,return,call,arith,move,float,multi" (const_string "arith")) @@ -943,60 +948,86 @@ DONE; }") -;; ??? Should have a bclr case here also. -;; ??? This should be symmetric with iorhi3. - (define_insn "andhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (and:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "rn")))] + [(set (match_operand:HI 0 "register_operand" "=r,r") + (and:HI (match_operand:HI 1 "register_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "J,rn")))] "" "* { if (GET_CODE (operands[2]) == CONST_INT) { int i = INTVAL (operands[2]); + if ((i & 0x00ff) != 0x00ff) output_asm_insn (\"and %s2,%s0\", operands); if ((i & 0xff00) != 0xff00) output_asm_insn (\"and %t2,%t0\", operands); return \"\"; } + if (TARGET_H8300H) + return \"and.w %T2,%T0\"; return \"and %s2,%s0\;and %t2,%t0;\"; }" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -;; ??? There is an iorsi3 for TARGET_H8300. Should we have andsi3? + [(set_attr "type" "arith,multi") + (set_attr "length" "2,4") + (set_attr "cc" "clobber,clobber")]) (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (and:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "TARGET_H8300H" - "@ - and %S2,%S0 - and %S2,%S0" - [(set_attr "type" "arith") - (set_attr "length" "4,6") - (set_attr "cc" "set")]) + (match_operand:SI 2 "nonmemory_operand" "J,rn")))] + "" + "* +{ + if (GET_CODE (operands[2]) == CONST_INT) + { + int i = INTVAL (operands[2]); + + /* ??? If we used e0..e7, then we could sub.w eX,eX to + clear the high word if (i & 0xffff0000) == 0. */ + + /* The h8300h can't do byte-wise operations on the + upper 16bits of 32bit registers. However, if + those bits aren't going to change, then we can + work on the low-order bits. */ + if (TARGET_H8300H + && (i & 0xffff0000) != 0xffff0000) + return \"and.l %S2,%S0\"; + + if ((i & 0x000000ff) != 0x000000ff) + output_asm_insn (\"and %w2,%w0\", operands); + if ((i & 0x0000ff00) != 0x0000ff00) + output_asm_insn (\"and %x2,%x0\", operands); + if ((i & 0x00ff0000) != 0x00ff0000) + output_asm_insn (\"and %y2,%y0\", operands); + if ((i & 0xff000000) != 0xff000000) + output_asm_insn (\"and %z2,%z0\", operands); + return \"\"; + } + if (TARGET_H8300H) + return \"and.l %S2,%S0\"; + return \"and %w2,%w0\;and %x2,%x0\;and %y2,%y0\;and %z2,%z0\;\"; +}" + [(set_attr "type" "arith,multi") + (set_attr "length" "2,8") + (set_attr "cc" "clobber,clobber")]) ;; ---------------------------------------------------------------------- ;; OR INSTRUCTIONS ;; ---------------------------------------------------------------------- (define_insn "iorqi3_internal" - [(set (match_operand:QI 0 "bit_operand" "=U,r") + [(set (match_operand:QI 0 "bit_operand" "=r,U") (ior:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "P,rn")))] + (match_operand:QI 2 "nonmemory_operand" "rn,P")))] "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)" "@ - bset %V2,%R0 - or %X2,%X0" + or %X2,%X0 + bset %V2,%R0" [(set_attr "type" "arith") - (set_attr "length" "4,2") - (set_attr "cc" "none_0hit,set")]) + (set_attr "length" "2,4") + (set_attr "cc" "set,none_0hit")]) (define_expand "iorqi3" [(set (match_operand:QI 0 "bit_operand" "=r,U") @@ -1009,9 +1040,6 @@ DONE; }") -;; ??? Should have a bset case here also. -;; ??? This should be symmetric with andhi3. - (define_insn "iorhi3" [(set (match_operand:HI 0 "general_operand" "=r,r") (ior:HI (match_operand:HI 1 "general_operand" "%0,0") @@ -1019,60 +1047,60 @@ "" "* { - if (TARGET_H8300) + if (GET_CODE (operands[2]) == CONST_INT) { - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if ((i & 0x00ff) != 0) - output_asm_insn (\"or %s2,%s0\", operands); - if ((i & 0xff00) != 0) - output_asm_insn (\"or %t2,%t0\", operands); - return \"\"; - } - return \"or %s2,%s0\;or %t2,%t0; %2 or2\"; - } - else - { - return \"or %S2,%S0\"; + int i = INTVAL (operands[2]); + + if ((i & 0x00ff) != 0) + output_asm_insn (\"or %s2,%s0\", operands); + if ((i & 0xff00) != 0) + output_asm_insn (\"or %t2,%t0\", operands); + return \"\"; } + if (TARGET_H8300H) + return \"or.w %T2,%T0\"; + return \"or %s2,%s0\;or %t2,%t0; %2 or2\"; }" - [(set_attr "type" "multi") + [(set_attr "type" "arith,multi") (set_attr "length" "2,4") (set_attr "cc" "clobber,clobber")]) (define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonmemory_operand" "ri")))] + [(set (match_operand:SI 0 "register_operand" "=r,r") + (ior:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "nonmemory_operand" "J,rn")))] "" "* { - if (TARGET_H8300) + if (GET_CODE (operands[2]) == CONST_INT) { - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if ((i & 0x000000ff) != 0) - output_asm_insn (\"or %w2,%w0\", operands); - if ((i & 0x0000ff00) != 0) - output_asm_insn (\"or %x2,%x0\", operands); - if ((i & 0x00ff0000) != 0) - output_asm_insn (\"or %y2,%y0\", operands); - if ((i & 0xff000000) != 0) - output_asm_insn (\"or %z2,%z0\", operands); - return \"\"; - } - return \"or %w2,%w0\;or %x2,%x0\;or %y2,%y0\;or %z2,%z0\;\"; - } - else - { - return \"or %S2,%S0\"; + int i = INTVAL (operands[2]); + + /* The h8300h can't do byte-wise operations on the + upper 16bits of 32bit registers. However, if + those bits aren't going to change, then we can + work on the low-order bits. */ + if (TARGET_H8300H + && (i & 0xffff0000) != 0x00000000) + return \"or.l %S2,%S0\"; + + if ((i & 0x000000ff) != 0) + output_asm_insn (\"or %w2,%w0\", operands); + if ((i & 0x0000ff00) != 0) + output_asm_insn (\"or %x2,%x0\", operands); + if ((i & 0x00ff0000) != 0) + output_asm_insn (\"or %y2,%y0\", operands); + if ((i & 0xff000000) != 0) + output_asm_insn (\"or %z2,%z0\", operands); + return \"\"; } + if (TARGET_H8300H) + return \"or.l %S2,%S0\"; + return \"or %w2,%w0\;or %x2,%x0\;or %y2,%y0\;or %z2,%z0\;\"; }" - [(set_attr "type" "multi") - (set_attr "length" "8") - (set_attr "cc" "clobber")]) + [(set_attr "type" "arith,multi") + (set_attr "length" "2,8") + (set_attr "cc" "clobber,clobber")]) ;; ---------------------------------------------------------------------- ;; XOR INSTRUCTIONS @@ -1101,37 +1129,67 @@ DONE; }") -;; ??? This should be symmetric with andhi3. - (define_insn "xorhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "rn")))] + [(set (match_operand:HI 0 "register_operand" "=r,r") + (xor:HI (match_operand:HI 1 "general_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "J,rn")))] "" "* { - if (TARGET_H8300) - return \"xor %s2,%s0\;xor %t2,%t0\"; - else - return \"xor %S2,%S0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) + if (GET_CODE (operands[2]) == CONST_INT) + { + int i = INTVAL (operands[2]); -;; ??? There is an iorsi3 for TARGET_H8300. Should we have xorsi3? + if ((i & 0x00ff) != 0) + output_asm_insn (\"xor %s2,%s0\", operands); + if ((i & 0xff00) != 0) + output_asm_insn (\"xor %t2,%t0\", operands); + return \"\"; + } + if (TARGET_H8300H) + return \"xor.w %T2,%T0\"; + return \"xor %s2,%s0\;xor %t2,%t0\"; +}" + [(set_attr "type" "arith,multi") + (set_attr "length" "2,4") + (set_attr "cc" "clobber,clobber")]) (define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (xor:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "TARGET_H8300H" - "@ - xor %S2,%S0 - xor %S2,%S0" - [(set_attr "type" "arith") - (set_attr "length" "4,6") - (set_attr "cc" "set")]) + (match_operand:SI 2 "nonmemory_operand" "J,rn")))] + "" + "* +{ + if (GET_CODE (operands[2]) == CONST_INT) + { + int i = INTVAL (operands[2]); + + /* The h8300h can't do byte-wise operations on the + upper 16bits of 32bit registers. However, if + those bits aren't going to change, then we can + work on the low-order bits. */ + if (TARGET_H8300H + && (i & 0xffff0000) != 0x00000000) + return \"xor.l %S2,%S0\"; + + if ((i & 0x000000ff) != 0) + output_asm_insn (\"xor %w2,%w0\", operands); + if ((i & 0x0000ff00) != 0) + output_asm_insn (\"xor %x2,%x0\", operands); + if ((i & 0x00ff0000) != 0) + output_asm_insn (\"xor %y2,%y0\", operands); + if ((i & 0xff000000) != 0) + output_asm_insn (\"xor %z2,%z0\", operands); + return \"\"; + } + if (TARGET_H8300H) + return \"xor.l %S2,%S0\"; + return \"xor %w2,%w0\;xor %x2,%x0\;xor %y2,%y0\;xor %z2,%z0\;\"; +}" + [(set_attr "type" "arith,multi") + (set_attr "length" "2,8") + (set_attr "cc" "clobber,clobber")]) ;; ---------------------------------------------------------------------- ;; NEGATION INSTRUCTIONS @@ -1233,8 +1291,11 @@ return \"not %T0\"; }" [(set_attr "type" "arith") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) + (set_attr "cc" "clobber") + (set (attr "length") + (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) + (const_int 8) + (const_int 2)))]) (define_insn "one_cmplsi2" [(set (match_operand:SI 0 "register_operand" "=r") @@ -1252,7 +1313,7 @@ (set (attr "length") (if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0)) (const_int 8) - (const_int 4)))]) + (const_int 2)))]) ;; ----------------------------------------------------------------------