h8300-protos.h: Add a prototype for emit_logical_op.
* config/h8300/h8300-protos.h: Add a prototype for emit_logical_op. * config/h8300/h8300.c (emit_logical_op): New. * config/h8300/h8300.md (andhi3): Use emit_logical_op. (andsi3): Likewise. (iorhi3): Likewise. (iorsi3): Likewise. (xorhi3): Likewise. (xorsi3): Likewise. From-SVN: r45272
This commit is contained in:
parent
6e9c53b489
commit
366a7b2715
gcc
@ -1,3 +1,15 @@
|
||||
2001-08-29 Kazu Hirata <kazu@hxi.com>
|
||||
|
||||
* config/h8300/h8300-protos.h: Add a prototype for
|
||||
emit_logical_op.
|
||||
* config/h8300/h8300.c (emit_logical_op): New.
|
||||
* config/h8300/h8300.md (andhi3): Use emit_logical_op.
|
||||
(andsi3): Likewise.
|
||||
(iorhi3): Likewise.
|
||||
(iorsi3): Likewise.
|
||||
(xorhi3): Likewise.
|
||||
(xorsi3): Likewise.
|
||||
|
||||
2001-08-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
|
||||
|
||||
* pa.c (move_operand): Cast GET_MODE_SIZE results to HOST_WIDE_INT for
|
||||
|
@ -37,6 +37,7 @@ extern void print_operand PARAMS ((FILE *, rtx, int));
|
||||
extern void final_prescan_insn PARAMS ((rtx, rtx *, int));
|
||||
extern int do_movsi PARAMS ((rtx[]));
|
||||
extern void notice_update_cc PARAMS ((rtx, rtx));
|
||||
extern const char *output_logical_op PARAMS ((enum machine_mode, int, rtx *));
|
||||
extern int expand_a_shift PARAMS ((enum machine_mode, int, rtx[]));
|
||||
extern int expand_a_rotate PARAMS ((int, rtx[]));
|
||||
extern int fix_bit_operand PARAMS ((rtx *, int, enum rtx_code));
|
||||
|
@ -1601,6 +1601,150 @@ bit_operator (x, mode)
|
||||
|| code == IOR);
|
||||
}
|
||||
|
||||
const char *
|
||||
output_logical_op (mode, code, operands)
|
||||
enum machine_mode mode;
|
||||
int code;
|
||||
rtx *operands;
|
||||
{
|
||||
/* Pretend that every byte is affected if both operands are registers. */
|
||||
unsigned HOST_WIDE_INT intval =
|
||||
(unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT)
|
||||
? INTVAL (operands[2]) : 0x55555555);
|
||||
/* The determinant of the algorithm. If we perform an AND, 0
|
||||
affects a bit. Otherwise, 1 affects a bit. */
|
||||
unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval;
|
||||
/* The name of an insn. */
|
||||
const char *opname;
|
||||
char insn_buf[100];
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case AND:
|
||||
opname = "and";
|
||||
break;
|
||||
case IOR:
|
||||
opname = "or";
|
||||
break;
|
||||
case XOR:
|
||||
opname = "xor";
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case HImode:
|
||||
/* First, see if we can finish with one insn. */
|
||||
if ((TARGET_H8300H || TARGET_H8300S)
|
||||
&& ((det & 0x00ff) != 0)
|
||||
&& ((det & 0xff00) != 0))
|
||||
{
|
||||
sprintf (insn_buf, "%s.w\t%%T2,%%T0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take care of the lower byte. */
|
||||
if ((det & 0x00ff) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s\t%%s2,%%s0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
/* Take care of the upper byte. */
|
||||
if ((det & 0xff00) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s\t%%t2,%%t0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SImode:
|
||||
/* First, see if we can finish with one insn.
|
||||
|
||||
If code is either AND or XOR, we exclude two special cases,
|
||||
0xffffff00 and 0xffff00ff, because insns like sub.w or neg.w
|
||||
can do a better job. */
|
||||
if ((TARGET_H8300H || TARGET_H8300S)
|
||||
&& ((det & 0x0000ffff) != 0)
|
||||
&& ((det & 0xffff0000) != 0)
|
||||
&& (code == IOR || det != 0xffffff00)
|
||||
&& (code == IOR || det != 0xffff00ff))
|
||||
{
|
||||
sprintf (insn_buf, "%s.l\t%%S2,%%S0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Take care of the lower and upper words individually. For
|
||||
each word, we try different methods in the order of
|
||||
|
||||
1) the special insn (in case of AND or XOR),
|
||||
2) the word-wise insn, and
|
||||
3) The byte-wise insn. */
|
||||
if ((TARGET_H8300H || TARGET_H8300S)
|
||||
&& ((det & 0x0000ffff) == 0x0000ffff)
|
||||
&& code != IOR)
|
||||
output_asm_insn ((code == AND)
|
||||
? "sub.w\t%f0,%f0" : "neg.w\t%f0",
|
||||
operands);
|
||||
else if ((TARGET_H8300H || TARGET_H8300S)
|
||||
&& ((det & 0x000000ff) != 0)
|
||||
&& ((det & 0x0000ff00) != 0))
|
||||
{
|
||||
sprintf (insn_buf, "%s.w\t%%f2,%%f0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((det & 0x000000ff) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s\t%%w2,%%w0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
if ((det & 0x0000ff00) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s\t%%x2,%%x0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
}
|
||||
|
||||
if ((TARGET_H8300H || TARGET_H8300S)
|
||||
&& ((det & 0xffff0000) == 0xffff0000)
|
||||
&& code != IOR)
|
||||
output_asm_insn ((code == AND)
|
||||
? "sub.w\t%e0,%e0" : "neg.w\t%e0",
|
||||
operands);
|
||||
else if (TARGET_H8300H || TARGET_H8300S)
|
||||
{
|
||||
if ((det & 0xffff0000) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s.w\t%%e2,%%e0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((det & 0x00ff0000) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s\t%%y2,%%y0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
if ((det & 0xff000000) != 0)
|
||||
{
|
||||
sprintf (insn_buf, "%s\t%%z2,%%z0", opname);
|
||||
output_asm_insn (insn_buf, operands);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Shifts.
|
||||
|
||||
We devote a fair bit of code to getting efficient shifts since we can only
|
||||
|
@ -988,83 +988,55 @@
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "andhi3"
|
||||
(define_expand "andhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "")
|
||||
(and:HI (match_operand:HI 1 "register_operand" "")
|
||||
(match_operand:HI 2 "nonmemory_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(and:HI (match_operand:HI 1 "register_operand" "%0")
|
||||
(match_operand:HI 2 "nonmemory_operand" "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 || TARGET_H8300S)
|
||||
return \"and.w %T2,%T0\";
|
||||
return \"and %s2,%s0\;and %t2,%t0;\";
|
||||
}"
|
||||
"TARGET_H8300"
|
||||
"* return output_logical_op (HImode, AND, operands);"
|
||||
[(set_attr "length" "4")
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "andsi3"
|
||||
(define_insn ""
|
||||
[(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" "r,n")))]
|
||||
"TARGET_H8300H || TARGET_H8300S"
|
||||
"* return output_logical_op (HImode, AND, operands);"
|
||||
[(set_attr "length" "2,4")
|
||||
(set_attr "cc" "set_znv,clobber")])
|
||||
|
||||
(define_expand "andsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(and:SI (match_operand:SI 1 "register_operand" "")
|
||||
(match_operand:SI 2 "nonmemory_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(and:SI (match_operand:SI 1 "register_operand" "%0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "rn")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
int i = INTVAL (operands[2]);
|
||||
int upper_cleared, lower_cleared;
|
||||
|
||||
/* The h8300h can't do byte-wise operations on the
|
||||
upper 16bits of 32bit registers. However, if
|
||||
those bits aren't going to change, or they're
|
||||
going to be zero'd out, then we can work on the
|
||||
low-order bits. */
|
||||
if ((TARGET_H8300H || TARGET_H8300S)
|
||||
&& ((i & 0xffff0000) != 0xffff0000
|
||||
|| (i & 0xffff0000) == 0x00000000))
|
||||
return \"and.l %S2,%S0\";
|
||||
|
||||
lower_cleared = 0;
|
||||
if ((i & 0x0000ffff) == 0x00000000)
|
||||
{
|
||||
output_asm_insn (\"sub.w %f0,%f0\", operands);
|
||||
lower_cleared = 1;
|
||||
}
|
||||
|
||||
upper_cleared = 0;
|
||||
if ((i & 0xffff0000) == 0x00000000)
|
||||
{
|
||||
output_asm_insn (\"sub.w %e0,%e0\", operands);
|
||||
upper_cleared = 1;
|
||||
}
|
||||
|
||||
if ((i & 0x000000ff) != 0x000000ff && !lower_cleared)
|
||||
output_asm_insn (\"and %w2,%w0\", operands);
|
||||
if ((i & 0x0000ff00) != 0x0000ff00 && !lower_cleared)
|
||||
output_asm_insn (\"and %x2,%x0\", operands);
|
||||
if ((i & 0x00ff0000) != 0x00ff0000 && !upper_cleared)
|
||||
output_asm_insn (\"and %y2,%y0\", operands);
|
||||
if ((i & 0xff000000) != 0xff000000 && !upper_cleared)
|
||||
output_asm_insn (\"and %z2,%z0\", operands);
|
||||
return \"\";
|
||||
}
|
||||
if (TARGET_H8300H || TARGET_H8300S)
|
||||
return \"and.l %S2,%S0\";
|
||||
return \"and %w2,%w0\;and %x2,%x0\;and %y2,%y0\;and %z2,%z0\";
|
||||
}"
|
||||
"TARGET_H8300"
|
||||
"* return output_logical_op (SImode, AND, operands);"
|
||||
[(set_attr "length" "8")
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn ""
|
||||
[(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,n")))]
|
||||
"TARGET_H8300H || TARGET_H8300S"
|
||||
"* return output_logical_op (SImode, AND, operands);"
|
||||
[(set_attr "length" "4,6")
|
||||
(set_attr "cc" "set_znv,clobber")])
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; OR INSTRUCTIONS
|
||||
@ -1093,66 +1065,56 @@
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "iorhi3"
|
||||
(define_expand "iorhi3"
|
||||
[(set (match_operand:HI 0 "general_operand" "=r,r")
|
||||
(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
|
||||
(match_operand:HI 2 "general_operand" "J,rn")))]
|
||||
""
|
||||
"*
|
||||
{
|
||||
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 \"\";
|
||||
}
|
||||
if (TARGET_H8300H || TARGET_H8300S)
|
||||
return \"or.w %T2,%T0\";
|
||||
return \"or %s2,%s0\;or %t2,%t0; %2 or2\";
|
||||
}"
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "general_operand" "=r,r")
|
||||
(ior:HI (match_operand:HI 1 "general_operand" "%0,0")
|
||||
(match_operand:HI 2 "general_operand" "J,rn")))]
|
||||
"TARGET_H8300"
|
||||
"* return output_logical_op (HImode, IOR, operands);"
|
||||
[(set_attr "length" "2,4")
|
||||
(set_attr "cc" "clobber,clobber")])
|
||||
|
||||
(define_insn "iorsi3"
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "general_operand" "=r,r,r")
|
||||
(ior:HI (match_operand:HI 1 "general_operand" "%0,0,0")
|
||||
(match_operand:HI 2 "general_operand" "J,r,n")))]
|
||||
"TARGET_H8300H || TARGET_H8300S"
|
||||
"* return output_logical_op (HImode, IOR, operands);"
|
||||
[(set_attr "length" "2,2,4")
|
||||
(set_attr "cc" "clobber,set_znv,clobber")])
|
||||
|
||||
(define_expand "iorsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(ior:SI (match_operand:SI 1 "register_operand" "")
|
||||
(match_operand:SI 2 "nonmemory_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(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 (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 || TARGET_H8300S)
|
||||
&& (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 || TARGET_H8300S)
|
||||
return \"or.l %S2,%S0\";
|
||||
return \"or %w2,%w0\;or %x2,%x0\;or %y2,%y0\;or %z2,%z0\";
|
||||
}"
|
||||
"TARGET_H8300"
|
||||
"* return output_logical_op (SImode, IOR, operands);"
|
||||
[(set_attr "length" "2,8")
|
||||
(set_attr "cc" "clobber,clobber")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
||||
(ior:SI (match_operand:SI 1 "register_operand" "%0,0,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "J,r,n")))]
|
||||
"TARGET_H8300H || TARGET_H8300S"
|
||||
"* return output_logical_op (SImode, IOR, operands);"
|
||||
[(set_attr "length" "2,4,6")
|
||||
(set_attr "cc" "clobber,set_znv,clobber")])
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; XOR INSTRUCTIONS
|
||||
;; ----------------------------------------------------------------------
|
||||
@ -1180,65 +1142,55 @@
|
||||
DONE;
|
||||
}")
|
||||
|
||||
(define_insn "xorhi3"
|
||||
(define_expand "xorhi3"
|
||||
[(set (match_operand:HI 0 "register_operand" "")
|
||||
(xor:HI (match_operand:HI 1 "general_operand" "")
|
||||
(match_operand:HI 2 "nonmemory_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(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 (GET_CODE (operands[2]) == CONST_INT)
|
||||
{
|
||||
int i = INTVAL (operands[2]);
|
||||
|
||||
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 || TARGET_H8300S)
|
||||
return \"xor.w %T2,%T0\";
|
||||
return \"xor %s2,%s0\;xor %t2,%t0\";
|
||||
}"
|
||||
"TARGET_H8300"
|
||||
"* return output_logical_op (HImode, XOR, operands);"
|
||||
[(set_attr "length" "2,4")
|
||||
(set_attr "cc" "clobber,clobber")])
|
||||
|
||||
(define_insn "xorsi3"
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
|
||||
(xor:HI (match_operand:HI 1 "general_operand" "%0,0,0")
|
||||
(match_operand:HI 2 "nonmemory_operand" "J,r,n")))]
|
||||
"TARGET_H8300H || TARGET_H8300S"
|
||||
"* return output_logical_op (HImode, XOR, operands);"
|
||||
[(set_attr "length" "2,2,4")
|
||||
(set_attr "cc" "clobber,set_znv,clobber")])
|
||||
|
||||
(define_expand "xorsi3"
|
||||
[(set (match_operand:SI 0 "register_operand" "")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "")
|
||||
(match_operand:SI 2 "nonmemory_operand" "")))]
|
||||
""
|
||||
"")
|
||||
|
||||
(define_insn ""
|
||||
[(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" "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 || TARGET_H8300S)
|
||||
&& (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 || TARGET_H8300S)
|
||||
return \"xor.l %S2,%S0\";
|
||||
return \"xor %w2,%w0\;xor %x2,%x0\;xor %y2,%y0\;xor %z2,%z0\";
|
||||
}"
|
||||
"TARGET_H8300"
|
||||
"* return output_logical_op (SImode, XOR, operands);"
|
||||
[(set_attr "length" "2,8")
|
||||
(set_attr "cc" "clobber,clobber")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
|
||||
(xor:SI (match_operand:SI 1 "register_operand" "%0,0,0")
|
||||
(match_operand:SI 2 "nonmemory_operand" "J,r,n")))]
|
||||
"TARGET_H8300H || TARGET_H8300S"
|
||||
"* return output_logical_op (SImode, XOR, operands);"
|
||||
[(set_attr "length" "2,4,6")
|
||||
(set_attr "cc" "clobber,set_znv,clobber")])
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; NEGATION INSTRUCTIONS
|
||||
|
Loading…
Reference in New Issue
Block a user