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
This commit is contained in:
parent
70cff8f545
commit
953b10d0d7
@ -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)))])
|
||||
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user