;; 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"))
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")
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")
""
"*
{
- if (TARGET_H8300)
- {
- 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
+ if (GET_CODE (operands[2]) == CONST_INT)
{
- 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)
- {
- 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
+ if (GET_CODE (operands[2]) == CONST_INT)
{
- 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
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")])
\f
;; ----------------------------------------------------------------------
;; NEGATION INSTRUCTIONS
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")
(set (attr "length")
(if_then_else (eq (symbol_ref "TARGET_H8300H") (const_int 0))
(const_int 8)
- (const_int 4)))])
+ (const_int 2)))])
\f
;; ----------------------------------------------------------------------