Commit a45d420a by Nick Clifton Committed by Nick Clifton

mn10300.c: Include tm-constrs.h.

	* config/mn10300/mn10300.c: Include tm-constrs.h.
	(struct liw_data): New data structure describing an LIW candidate
	instruction.
	(extract_bundle): Use struct liw_data.  Allow small integer
	operands for some instructions.
	(check_liw_constraints): Use struct liw_data.  Remove swapped
	parameter.  Add comments describing the checks.  Fix bug when
	assigning the source of liw1 to the source of liw2.
	(liw_candidate): Delete.  Code moved into extract_bundle.
	(mn10300_bundle_liw): Use struct liw_data.  Check constraints
	before swapping.
	* config/mn10300/predicates.md (liw_operand): New predicate.
	Allows registers and small integer constants.
	* config/mn10300/constraints.md (O): New constraint.  Accetps
	integers in the range -8 to +7 inclusive.
	* config/mn10300/mn10300.md (movesi_internal): Add an alternative
	for moving a small integer into a register.  Give this alternative
	LIW attributes.
	(addsi3, subsi3, cmpsi, lshrsi3, ashrsi3): Likewise.
	(ashlsi3): Likewise, plus give LIW attributes to the alternatives
	using the J,K,L and M constraints,
	(liw): Remove SI mode on second operands to allow for HI and QI
	mode values.
	(cmp_liw, liw_cmp): Likewise.  Plus fix order of operands in the
	instruction.

From-SVN: r170182
parent 8a73faf1
2011-02-15 Nick Clifton <nickc@redhat.com>
* config/mn10300/mn10300.c: Include tm-constrs.h.
(struct liw_data): New data structure describing an LIW candidate
instruction.
(extract_bundle): Use struct liw_data. Allow small integer
operands for some instructions.
(check_liw_constraints): Use struct liw_data. Remove swapped
parameter. Add comments describing the checks. Fix bug when
assigning the source of liw1 to the source of liw2.
(liw_candidate): Delete. Code moved into extract_bundle.
(mn10300_bundle_liw): Use struct liw_data. Check constraints
before swapping.
* config/mn10300/predicates.md (liw_operand): New predicate.
Allows registers and small integer constants.
* config/mn10300/constraints.md (O): New constraint. Accetps
integers in the range -8 to +7 inclusive.
* config/mn10300/mn10300.md (movesi_internal): Add an alternative
for moving a small integer into a register. Give this alternative
LIW attributes.
(addsi3, subsi3, cmpsi, lshrsi3, ashrsi3): Likewise.
(ashlsi3): Likewise, plus give LIW attributes to the alternatives
using the J,K,L and M constraints,
(liw): Remove SI mode on second operands to allow for HI and QI
mode values.
(cmp_liw, liw_cmp): Likewise. Plus fix order of operands in the
instruction.
2011-02-15 H.J. Lu <hongjiu.lu@intel.com> 2011-02-15 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/47725 PR middle-end/47725
......
...@@ -94,6 +94,12 @@ ...@@ -94,6 +94,12 @@
(ior (match_test "ival == 255") (ior (match_test "ival == 255")
(match_test "ival == 65535")))) (match_test "ival == 65535"))))
(define_constraint "O"
"An integer between -8 and +7 inclusive."
(and (match_code "const_int")
(and (match_test "ival >= -8")
(match_test "ival <= 7"))))
;; Floating-point constraints ;; Floating-point constraints
(define_constraint "G" (define_constraint "G"
"Floating-point zero." "Floating-point zero."
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "obstack.h" #include "obstack.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "tm_p.h" #include "tm_p.h"
#include "tm-constrs.h"
#include "target.h" #include "target.h"
#include "target-def.h" #include "target-def.h"
#include "df.h" #include "df.h"
...@@ -2945,91 +2946,143 @@ mn10300_split_and_operand_count (rtx op) ...@@ -2945,91 +2946,143 @@ mn10300_split_and_operand_count (rtx op)
} }
} }
/* Extract operands and (if requested) the LIW op type from the insn. struct liw_data
Returns false if the insn can't be bundled. */ {
enum attr_liw slot;
enum attr_liw_op op;
rtx dest;
rtx src;
};
/* Decide if the given insn is a candidate for LIW bundling. If it is then
extract the operands and LIW attributes from the insn and use them to fill
in the liw_data structure. Return true upon success or false if the insn
cannot be bundled. */
static bool static bool
extract_bundle (rtx insn, rtx * ops, enum attr_liw_op * plop) extract_bundle (rtx insn, struct liw_data * pdata)
{ {
enum attr_liw_op lop; bool allow_consts = true;
rtx p, s; rtx p,s;
gcc_assert (pdata != NULL);
if (insn == NULL_RTX)
return false;
/* Make sure that we are dealing with a simple SET insn. */
p = single_set (insn); p = single_set (insn);
if (p == NULL_RTX)
return false;
/* Make sure that it could go into one of the LIW pipelines. */
pdata->slot = get_attr_liw (insn);
if (pdata->slot == LIW_BOTH)
return false;
pdata->op = get_attr_liw_op (insn);
s = SET_SRC (p); s = SET_SRC (p);
lop = get_attr_liw_op (insn);
if (plop != NULL)
* plop = lop;
switch (lop) switch (pdata->op)
{ {
case LIW_OP_MOV: case LIW_OP_MOV:
ops[0] = SET_DEST (p); pdata->dest = SET_DEST (p);
ops[1] = SET_SRC (p); pdata->src = SET_SRC (p);
break; break;
case LIW_OP_CMP: case LIW_OP_CMP:
ops[0] = XEXP (SET_SRC (p), 0); pdata->dest = XEXP (SET_SRC (p), 0);
ops[1] = XEXP (SET_SRC (p), 1); pdata->src = XEXP (SET_SRC (p), 1);
break; break;
case LIW_OP_NONE: case LIW_OP_NONE:
return false; return false;
case LIW_OP_AND:
case LIW_OP_OR:
case LIW_OP_XOR:
/* The AND, OR and XOR long instruction words only accept register arguments. */
allow_consts = false;
/* Fall through. */
default: default:
ops[0] = SET_DEST (p); pdata->dest = SET_DEST (p);
ops[1] = XEXP (SET_SRC (p), 1); pdata->src = XEXP (SET_SRC (p), 1);
break; break;
} }
return REG_P (ops[0]) && REG_P (ops[1]); if (! REG_P (pdata->dest))
return false;
if (REG_P (pdata->src))
return true;
return allow_consts && satisfies_constraint_O (pdata->src);
} }
/* Look for conflicts in the operands used in /* Make sure that it is OK to execute LIW1 and LIW2 in parallel. GCC generated
the potential bundling of the two insns. */ the instructions with the assumption that LIW1 would be executed before LIW2
so we must check for overlaps between their sources and destinations. */
static bool static bool
check_liw_constraints (rtx ops[4], check_liw_constraints (struct liw_data * pliw1, struct liw_data * pliw2)
enum attr_liw_op op1, {
enum attr_liw_op op2, /* Check for slot conflicts. */
bool swapped) if (pliw2->slot == pliw1->slot && pliw1->slot != LIW_EITHER)
{
/* Look for the two destination registers being the same. This is OK if
the first op is a comparison op, since it will compare the value prior
to the completion of the second op. */
if (REGNO (ops[0]) == REGNO (ops[2])
&& ( (! swapped && op1 != LIW_OP_CMP)
|| (swapped && op2 != LIW_OP_CMP)))
return false; return false;
/* Look for the source of the second op being the destination of the first op. /* If either operation is a compare, then "dest" is really an input; the real
Nomrally this will prevent the bundling since GCC has generated sequential destination is CC_REG. So these instructions need different checks. */
operations and the LIW opcodes are executed in parallel. But if the first
opcode is a MOV, we can copy its source to the second ops source. */ /* Changing "CMP ; OP" into "CMP | OP" is OK because the comparison will
if (swapped) check its values prior to any changes made by OP. */
return REGNO (ops[1]) != REGNO (ops[2]); if (pliw1->op == LIW_OP_CMP)
{
/* Two sequential comparisons means dead code, which ought to
have been eliminated given that bundling only happens with
optimization. We cannot bundle them in any case. */
gcc_assert (pliw1->op != pliw2->op);
return true;
}
if (REGNO (ops[3]) == REGNO (ops[0])) /* Changing "OP ; CMP" into "OP | CMP" does not work if the value being compared
is the destination of OP, as the CMP will look at the old value, not the new
one. */
if (pliw2->op == LIW_OP_CMP)
{ {
if (op1 == LIW_OP_MOV) if (REGNO (pliw2->dest) == REGNO (pliw1->dest))
return false;
if (REG_P (pliw2->src))
return REGNO (pliw2->src) != REGNO (pliw1->dest);
return true;
}
/* Changing "OP1 ; OP2" into "OP1 | OP2" does not work if they both write to the
same destination register. */
if (REGNO (pliw2->dest) == REGNO (pliw1->dest))
return false;
/* Changing "OP1 ; OP2" into "OP1 | OP2" generally does not work if the destination
of OP1 is the source of OP2. The exception is when OP1 is a MOVE instruction when
we can replace the source in OP2 with the source of OP1. */
if (REG_P (pliw2->src) && REGNO (pliw2->src) == REGNO (pliw1->dest))
{
if (pliw1->op == LIW_OP_MOV && REG_P (pliw1->src))
{ {
ops[3] = ops[1]; if (! REG_P (pliw1->src)
&& (pliw2->op == LIW_OP_AND
|| pliw2->op == LIW_OP_OR
|| pliw2->op == LIW_OP_XOR))
return false;
pliw2->src = pliw1->src;
return true; return true;
} }
return false; return false;
} }
/* Everything else is OK. */
return true; return true;
} }
/* Decide if the given insn is a candidate for LIW bundling. For now we just
check that the insn has an LIW attribute. Later on we check operand
constraints and such. */
static bool
liw_candidate (rtx insn)
{
return insn != NULL_RTX
&& single_set (insn) != NULL_RTX
&& get_attr_liw (insn) != LIW_BOTH;
}
/* Combine pairs of insns into LIW bundles. */ /* Combine pairs of insns into LIW bundles. */
static void static void
...@@ -3039,61 +3092,41 @@ mn10300_bundle_liw (void) ...@@ -3039,61 +3092,41 @@ mn10300_bundle_liw (void)
for (r = get_insns (); r != NULL_RTX; r = next_nonnote_nondebug_insn (r)) for (r = get_insns (); r != NULL_RTX; r = next_nonnote_nondebug_insn (r))
{ {
rtx insn1, insn2, ops[4]; rtx insn1, insn2;
enum attr_liw liw1, liw2; struct liw_data liw1, liw2;
enum attr_liw_op op1, op2;
bool swapped = false;
insn1 = r; insn1 = r;
if (! liw_candidate (insn1)) if (! extract_bundle (insn1, & liw1))
continue; continue;
insn2 = next_nonnote_nondebug_insn (insn1); insn2 = next_nonnote_nondebug_insn (insn1);
if (! liw_candidate (insn2)) if (! extract_bundle (insn2, & liw2))
continue; continue;
liw1 = get_attr_liw (insn1); /* Check for source/destination overlap. */
if (liw1 == LIW_BOTH) if (! check_liw_constraints (& liw1, & liw2))
continue;
liw2 = get_attr_liw (insn2);
if (liw2 == LIW_BOTH)
continue;
if (liw2 == liw1 && liw1 != LIW_EITHER)
continue; continue;
/* The scheduler always groups the insns correctly, but not if (liw1.slot == LIW_OP2 || liw2.slot == LIW_OP1)
always in sequence. So, we can do a naive check and expect
it to work. */
if (liw1 == LIW_OP2 || liw2 == LIW_OP1)
{ {
rtx r; struct liw_data temp;
enum attr_liw lt;
temp = liw1;
r = insn1;
insn1 = insn2;
insn2 = r;
lt = liw1;
liw1 = liw2; liw1 = liw2;
liw2 = lt; liw2 = temp;
swapped = true;
} }
if (! extract_bundle (insn1, ops, & op1))
continue;
if (! extract_bundle (insn2, ops + 2, & op2))
continue;
if (! check_liw_constraints (ops, op1, op2, swapped))
continue;
delete_insn (insn2); delete_insn (insn2);
if (op1 == LIW_OP_CMP) if (liw1.op == LIW_OP_CMP)
insn2 = gen_cmp_liw (ops[2], ops[3], ops[0], ops[1], GEN_INT (op2)); insn2 = gen_cmp_liw (liw2.dest, liw2.src, liw1.dest, liw1.src,
else if (op2 == LIW_OP_CMP) GEN_INT (liw2.op));
insn2 = gen_liw_cmp (ops[0], ops[1], ops[2], ops[3], GEN_INT (op1)); else if (liw2.op == LIW_OP_CMP)
insn2 = gen_liw_cmp (liw1.dest, liw1.src, liw2.dest, liw2.src,
GEN_INT (liw1.op));
else else
insn2 = gen_liw (ops[0], ops[2], ops[1], ops[3], insn2 = gen_liw (liw1.dest, liw2.dest, liw1.src, liw2.src,
GEN_INT (op1), GEN_INT (op2)); GEN_INT (liw1.op), GEN_INT (liw2.op));
insn2 = emit_insn_after (insn2, insn1); insn2 = emit_insn_after (insn2, insn1);
delete_insn (insn1); delete_insn (insn1);
......
...@@ -419,9 +419,9 @@ ...@@ -419,9 +419,9 @@
(define_insn "*movsi_internal" (define_insn "*movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand" [(set (match_operand:SI 0 "nonimmediate_operand"
"=r,r,r,m,r, A,*y,*y,*z,*d") "=r,r,r,r,m,r, A,*y,*y,*z,*d")
(match_operand:SI 1 "general_operand" (match_operand:SI 1 "general_operand"
" 0,i,r,r,m,*y, A, i,*d,*z"))] " 0,O,i,r,r,m,*y, A, i,*d,*z"))]
"register_operand (operands[0], SImode) "register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)" || register_operand (operands[1], SImode)"
{ {
...@@ -429,7 +429,8 @@ ...@@ -429,7 +429,8 @@
{ {
case 0: case 0:
return ""; return "";
case 1: /* imm-reg*/ case 1: /* imm-reg. */
case 2:
/* See movhi for a discussion of sizes for 8-bit movu. Note that the /* See movhi for a discussion of sizes for 8-bit movu. Note that the
24-bit movu is 6 bytes, which is the same size as the full 32-bit 24-bit movu is 6 bytes, which is the same size as the full 32-bit
mov form for An and Dn. So again movu is only a win for Rn. */ mov form for An and Dn. So again movu is only a win for Rn. */
...@@ -443,25 +444,26 @@ ...@@ -443,25 +444,26 @@
return "movu %1,%0"; return "movu %1,%0";
} }
/* FALLTHRU */ /* FALLTHRU */
case 2: /* reg-reg */ case 3: /* reg-reg */
case 3: /* reg-mem */ case 4: /* reg-mem */
case 4: /* mem-reg */ case 5: /* mem-reg */
case 5: /* sp-reg */ case 6: /* sp-reg */
case 6: /* reg-sp */ case 7: /* reg-sp */
case 7: /* imm-sp */ case 8: /* imm-sp */
case 8: /* reg-mdr */ case 9: /* reg-mdr */
case 9: /* mdr-reg */ case 10: /* mdr-reg */
return "mov %1,%0"; return "mov %1,%0";
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
} }
[(set_attr "isa" "*,*,*,*,*,*,*,am33,*,*") [(set_attr "isa" "*,*,*,*,*,*,*,*,am33,*,*")
(set_attr "liw" "*,*,either,*,*,*,*,*,*,*") (set_attr "liw" "*,either,*,either,*,*,*,*,*,*,*")
(set_attr "liw_op" "mov") (set_attr "liw_op" "mov")
(set_attr_alternative "timings" (set_attr_alternative "timings"
[(const_int 11) [(const_int 11)
(const_int 22) (const_int 22)
(const_int 22)
(const_int 11) (const_int 11)
(if_then_else (eq_attr "cpu" "am34") (if_then_else (eq_attr "cpu" "am34")
(const_int 11) (const_int 22)) (const_int 11) (const_int 22))
...@@ -563,14 +565,14 @@ ...@@ -563,14 +565,14 @@
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
(define_insn "addsi3" (define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,!*y,!r") [(set (match_operand:SI 0 "register_operand" "=r,r,r,!*y,!r")
(plus:SI (match_operand:SI 1 "register_operand" "%0,0, 0, r") (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0, 0, r")
(match_operand:SI 2 "nonmemory_operand" "r,i, i, r"))) (match_operand:SI 2 "nonmemory_operand" "r,O,i, i, r")))
(clobber (reg:CC CC_REG))] (clobber (reg:CC CC_REG))]
"" ""
{ return mn10300_output_add (operands, false); } { return mn10300_output_add (operands, false); }
[(set_attr "timings" "11,11,11,22") [(set_attr "timings" "11,11,11,11,22")
(set_attr "liw" "either,*,*,*") (set_attr "liw" "either,either,*,*,*")
(set_attr "liw_op" "add")] (set_attr "liw_op" "add")]
) )
...@@ -758,19 +760,20 @@ ...@@ -758,19 +760,20 @@
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
(define_insn "subsi3" (define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r") [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(minus:SI (match_operand:SI 1 "register_operand" "0,0,r") (minus:SI (match_operand:SI 1 "register_operand" "0,0,0,r")
(match_operand:SI 2 "nonmemory_operand" "r,i,r"))) (match_operand:SI 2 "nonmemory_operand" "r,O,i,r")))
(clobber (reg:CC CC_REG))] (clobber (reg:CC CC_REG))]
"" ""
"@ "@
sub %2,%0 sub %2,%0
sub %2,%0 sub %2,%0
sub %2,%0
sub %2,%1,%0" sub %2,%1,%0"
[(set_attr "isa" "*,*,am33") [(set_attr "isa" "*,*,*,am33")
(set_attr "liw" "either,*,*") (set_attr "liw" "either,either,*,*")
(set_attr "liw_op" "sub") (set_attr "liw_op" "sub")
(set_attr "timings" "11,11,22")] (set_attr "timings" "11,11,11,22")]
) )
(define_insn "*subsi3_flags" (define_insn "*subsi3_flags"
...@@ -1374,8 +1377,8 @@ ...@@ -1374,8 +1377,8 @@
(define_insn "*cmpsi" (define_insn "*cmpsi"
[(set (reg CC_REG) [(set (reg CC_REG)
(compare (match_operand:SI 0 "register_operand" "r,r") (compare (match_operand:SI 0 "register_operand" "r,r,r")
(match_operand:SI 1 "nonmemory_operand" "r,i")))] (match_operand:SI 1 "nonmemory_operand" "r,O,i")))]
"reload_completed" "reload_completed"
{ {
/* The operands of CMP must be distinct registers. In the case where /* The operands of CMP must be distinct registers. In the case where
...@@ -1390,8 +1393,9 @@ ...@@ -1390,8 +1393,9 @@
} }
[(set_attr_alternative "timings" [(set_attr_alternative "timings"
[(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22)) [(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))
(if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))]) (if_then_else (eq_attr "cpu" "am34") (const_int 11) (const_int 22))])
(set_attr "liw" "either,*") (set_attr "liw" "either,either,*")
(set_attr "liw_op" "cmp")] (set_attr "liw_op" "cmp")]
) )
...@@ -1732,10 +1736,10 @@ ...@@ -1732,10 +1736,10 @@
;; ---------------------------------------------------------------------- ;; ----------------------------------------------------------------------
(define_insn "ashlsi3" (define_insn "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,D,d,d,D,D,r") [(set (match_operand:SI 0 "register_operand" "=r,D,d,d,D,D,D,r")
(ashift:SI (ashift:SI
(match_operand:SI 1 "register_operand" " 0,0,0,0,0,0,r") (match_operand:SI 1 "register_operand" " 0,0,0,0,0,0,0,r")
(match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,i,r"))) (match_operand:QI 2 "nonmemory_operand" " J,K,M,L,D,O,i,r")))
(clobber (reg:CC CC_REG))] (clobber (reg:CC CC_REG))]
"" ""
"@ "@
...@@ -1745,42 +1749,45 @@ ...@@ -1745,42 +1749,45 @@
asl2 %0\;asl2 %0 asl2 %0\;asl2 %0
asl %S2,%0 asl %S2,%0
asl %S2,%0 asl %S2,%0
asl %S2,%0
asl %2,%1,%0" asl %2,%1,%0"
[(set_attr "isa" "*,*,*,*,*,*,am33") [(set_attr "isa" "*,*,*,*,*,*,*,am33")
(set_attr "liw" "*,*,*,*,op2,*,*") (set_attr "liw" "op2,op2,op2,op2,op2,op2,*,*")
(set_attr "liw_op" "asl") (set_attr "liw_op" "asl")
(set_attr "timings" "11,11,22,22,11,11,11")] (set_attr "timings" "11,11,22,22,11,11,11,11")]
) )
(define_insn "lshrsi3" (define_insn "lshrsi3"
[(set (match_operand:SI 0 "register_operand" "=D,D,r") [(set (match_operand:SI 0 "register_operand" "=D,D,D,r")
(lshiftrt:SI (lshiftrt:SI
(match_operand:SI 1 "register_operand" "0,0,r") (match_operand:SI 1 "register_operand" "0,0,0,r")
(match_operand:QI 2 "nonmemory_operand" "D,i,r"))) (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
(clobber (reg:CC CC_REG))] (clobber (reg:CC CC_REG))]
"" ""
"@ "@
lsr %S2,%0 lsr %S2,%0
lsr %S2,%0 lsr %S2,%0
lsr %S2,%0
lsr %2,%1,%0" lsr %2,%1,%0"
[(set_attr "isa" "*,*,am33") [(set_attr "isa" "*,*,*,am33")
(set_attr "liw" "op2,*,*") (set_attr "liw" "op2,op2,*,*")
(set_attr "liw_op" "lsr")] (set_attr "liw_op" "lsr")]
) )
(define_insn "ashrsi3" (define_insn "ashrsi3"
[(set (match_operand:SI 0 "register_operand" "=D,D,r") [(set (match_operand:SI 0 "register_operand" "=D,D,D,r")
(ashiftrt:SI (ashiftrt:SI
(match_operand:SI 1 "register_operand" "0,0,r") (match_operand:SI 1 "register_operand" "0,0,0,r")
(match_operand:QI 2 "nonmemory_operand" "D,i,r"))) (match_operand:QI 2 "nonmemory_operand" "D,O,i,r")))
(clobber (reg:CC CC_REG))] (clobber (reg:CC CC_REG))]
"" ""
"@ "@
asr %S2,%0 asr %S2,%0
asr %S2,%0 asr %S2,%0
asr %S2,%0
asr %2,%1,%0" asr %2,%1,%0"
[(set_attr "isa" "*,*,am33") [(set_attr "isa" "*,*,*,am33")
(set_attr "liw" "op2,*,*") (set_attr "liw" "op2,op2,*,*")
(set_attr "liw_op" "asr")] (set_attr "liw_op" "asr")]
) )
...@@ -2100,12 +2107,12 @@ ...@@ -2100,12 +2107,12 @@
(define_insn "liw" (define_insn "liw"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_dup 0) (unspec:SI [(match_dup 0)
(match_operand:SI 2 "register_operand" "r") (match_operand 2 "liw_operand" "rO")
(match_operand:SI 4 "const_int_operand" "")] (match_operand:SI 4 "const_int_operand" "")]
UNSPEC_LIW)) UNSPEC_LIW))
(set (match_operand:SI 1 "register_operand" "=r") (set (match_operand:SI 1 "register_operand" "=r")
(unspec:SI [(match_dup 1) (unspec:SI [(match_dup 1)
(match_operand 3 "register_operand" "r") (match_operand 3 "liw_operand" "rO")
(match_operand:SI 5 "const_int_operand" "")] (match_operand:SI 5 "const_int_operand" "")]
UNSPEC_LIW))] UNSPEC_LIW))]
"TARGET_ALLOW_LIW" "TARGET_ALLOW_LIW"
...@@ -2119,14 +2126,14 @@ ...@@ -2119,14 +2126,14 @@
(define_insn "cmp_liw" (define_insn "cmp_liw"
[(set (reg:CC CC_REG) [(set (reg:CC CC_REG)
(compare:CC (match_operand:SI 2 "register_operand" "r") (compare:CC (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "register_operand" "r"))) (match_operand 3 "liw_operand" "rO")))
(set (match_operand:SI 0 "register_operand" "=r") (set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_dup 0) (unspec:SI [(match_dup 0)
(match_operand 1 "register_operand" "r") (match_operand 1 "liw_operand" "rO")
(match_operand:SI 4 "const_int_operand" "")] (match_operand:SI 4 "const_int_operand" "")]
UNSPEC_LIW))] UNSPEC_LIW))]
"TARGET_ALLOW_LIW" "TARGET_ALLOW_LIW"
"cmp_%W4 %2, %3, %0, %1" "cmp_%W4 %3, %2, %1, %0"
[(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
(const_int 13) (const_int 12)))] (const_int 13) (const_int 12)))]
) )
...@@ -2134,14 +2141,14 @@ ...@@ -2134,14 +2141,14 @@
(define_insn "liw_cmp" (define_insn "liw_cmp"
[(set (match_operand:SI 0 "register_operand" "=r") [(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_dup 0) (unspec:SI [(match_dup 0)
(match_operand:SI 1 "register_operand" "r") (match_operand 1 "liw_operand" "rO")
(match_operand:SI 4 "const_int_operand" "")] (match_operand:SI 4 "const_int_operand" "")]
UNSPEC_LIW)) UNSPEC_LIW))
(set (reg:CC CC_REG) (set (reg:CC CC_REG)
(compare:CC (match_operand:SI 2 "register_operand" "r") (compare:CC (match_operand:SI 2 "register_operand" "r")
(match_operand:SI 3 "register_operand" "r")))] (match_operand 3 "liw_operand" "rO")))]
"TARGET_ALLOW_LIW" "TARGET_ALLOW_LIW"
"%W4_cmp %0, %1, %2, %3" "%W4_cmp %1, %0, %3, %2"
[(set (attr "timings") (if_then_else (eq_attr "cpu" "am34") [(set (attr "timings") (if_then_else (eq_attr "cpu" "am34")
(const_int 13) (const_int 12)))] (const_int 13) (const_int 12)))]
) )
...@@ -63,3 +63,7 @@ ...@@ -63,3 +63,7 @@
(define_predicate "CCZN_comparison_operator" (define_predicate "CCZN_comparison_operator"
(match_code "eq,ne,lt,ge")) (match_code "eq,ne,lt,ge"))
(define_predicate "liw_operand"
(ior (match_operand 0 "register_operand")
(match_test "satisfies_constraint_O (op)")))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment