Pushed. Thank you for your review,
Claudiu
On Fri, Sep 21, 2018 at 12:12 AM Andrew Burgess
<andrew.burg...@embecosm.com> wrote:
>
> * Claudiu Zissulescu <claz...@gmail.com> [2018-09-17 15:50:27 +0300]:
>
> > The 3-operand instructions accepts to place an immediate into the
> > second operand. However, this immediate will end up in the long
> > immediate field. This patch avoids constants to end up in the limm
> > field for particular instructions when compiling for size.
> >
> > gcc/
> > xxxx-xx-xx Claudiu Zissulescu <claz...@synopsys.com>
> >
> > * config/arc/arc.md (*add_n): Clean up pattern, update instruction
> > constraints.
> > (ashlsi3_insn): Update instruction constraints.
> > (ashrsi3_insn): Likewise.
> > (rotrsi3): Likewise.
> > (add_shift): Likewise.
> > * config/arc/constraints.md (Csz): New 32 bit constraint. It
> > avoids placing in the limm field small constants which, otherwise,
> > could end into a small instruction.
> > ---
> > gcc/config/arc/arc.md | 51 +++++++++---------------
> > gcc/config/arc/constraints.md | 6 +++
> > gcc/testsuite/gcc.target/arc/tph_addx.c | 53 +++++++++++++++++++++++++
> > 3 files changed, 78 insertions(+), 32 deletions(-)
> > create mode 100644 gcc/testsuite/gcc.target/arc/tph_addx.c
>
> Looks good.
>
> Thanks,
> Andrew
>
>
> >
> > diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> > index 2d108ef166d..c28a87cd3b0 100644
> > --- a/gcc/config/arc/arc.md
> > +++ b/gcc/config/arc/arc.md
> > @@ -3056,30 +3056,17 @@ core_3, archs4x, archs4xd, archs4xd_slow"
> > (set (match_dup 3) (match_dup 4))])
> >
> > (define_insn "*add_n"
> > - [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w")
> > - (plus:SI (ashift:SI (match_operand:SI 1 "register_operand"
> > "Rcqq,c,c,c,c,c")
> > - (match_operand:SI 2 "_1_2_3_operand" ""))
> > - (match_operand:SI 3 "nonmemory_operand"
> > "0,0,c,?Cal,?c,??Cal")))]
> > + [(set (match_operand:SI 0 "dest_reg_operand" "=q,r,r")
> > + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "q,r,r")
> > + (match_operand:SI 2 "_2_4_8_operand" ""))
> > + (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))]
> > ""
> > - "add%c2%? %0,%3,%1%&"
> > + "add%z2%?\\t%0,%3,%1%&"
> > [(set_attr "type" "shift")
> > - (set_attr "length" "*,4,4,8,4,8")
> > - (set_attr "predicable" "yes,yes,no,no,no,no")
> > - (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
> > - (set_attr "iscompact" "maybe,false,false,false,false,false")])
> > -
> > -(define_insn "*add_n"
> > - [(set (match_operand:SI 0 "dest_reg_operand"
> > "=Rcqq,Rcw,W, W,w,w")
> > - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq, c,c,
> > c,c,c")
> > - (match_operand:SI 2 "_2_4_8_operand" ""))
> > - (match_operand:SI 3 "nonmemory_operand" "0,
> > 0,c,Cal,c,Cal")))]
> > - ""
> > - "add%z2%? %0,%3,%1%&"
> > - [(set_attr "type" "shift")
> > - (set_attr "length" "*,4,4,8,4,8")
> > - (set_attr "predicable" "yes,yes,no,no,no,no")
> > - (set_attr "cond" "canuse,canuse,nocond,nocond,nocond,nocond")
> > - (set_attr "iscompact" "maybe,false,false,false,false,false")])
> > + (set_attr "length" "*,4,8")
> > + (set_attr "predicable" "yes,no,no")
> > + (set_attr "cond" "canuse,nocond,nocond")
> > + (set_attr "iscompact" "maybe,false,false")])
> >
> > ;; N.B. sub[123] has the operands of the MINUS in the opposite order from
> > ;; what synth_mult likes.
> > @@ -3496,7 +3483,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
> > ; provide one alternatice for this, without condexec support.
> > (define_insn "*ashlsi3_insn"
> > [(set (match_operand:SI 0 "dest_reg_operand"
> > "=Rcq,Rcqq,Rcqq,Rcw, w, w")
> > - (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0,
> > c,cCal")
> > + (ashift:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0, 0,
> > c,cCsz")
> > (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM,
> > cL,cL,cCal")))]
> > "TARGET_BARREL_SHIFTER
> > && (register_operand (operands[1], SImode)
> > @@ -3509,7 +3496,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
> >
> > (define_insn "*ashrsi3_insn"
> > [(set (match_operand:SI 0 "dest_reg_operand"
> > "=Rcq,Rcqq,Rcqq,Rcw, w, w")
> > - (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0,
> > 0, c,cCal")
> > + (ashiftrt:SI (match_operand:SI 1 "nonmemory_operand" "!0,Rcqq, 0,
> > 0, c,cCsz")
> > (match_operand:SI 2 "nonmemory_operand" "K, K,RcqqM,
> > cL,cL,cCal")))]
> > "TARGET_BARREL_SHIFTER
> > && (register_operand (operands[1], SImode)
> > @@ -3536,7 +3523,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
> >
> > (define_insn "rotrsi3"
> > [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw, w, w")
> > - (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCal")
> > + (rotatert:SI (match_operand:SI 1 "register_operand" " 0,cL,cCsz")
> > (match_operand:SI 2 "nonmemory_operand" "cL,cL,cCal")))]
> > "TARGET_BARREL_SHIFTER"
> > "ror%? %0,%1,%2"
> > @@ -4284,16 +4271,16 @@ core_3, archs4x, archs4xd, archs4xd_slow"
> > (define_peephole2
> > [(set (match_operand:SI 0 "dest_reg_operand" "")
> > (ashift:SI (match_operand:SI 1 "register_operand" "")
> > - (match_operand:SI 2 "const_int_operand" "")))
> > + (match_operand:SI 2 "_1_2_3_operand" "")))
> > (set (match_operand:SI 3 "dest_reg_operand" "")
> > (plus:SI (match_operand:SI 4 "nonmemory_operand" "")
> > (match_operand:SI 5 "nonmemory_operand" "")))]
> > - "(INTVAL (operands[2]) == 1
> > - || INTVAL (operands[2]) == 2
> > - || INTVAL (operands[2]) == 3)
> > - && (true_regnum (operands[4]) == true_regnum (operands[0])
> > + "(true_regnum (operands[4]) == true_regnum (operands[0])
> > || true_regnum (operands[5]) == true_regnum (operands[0]))
> > - && (peep2_reg_dead_p (2, operands[0]) || (true_regnum (operands[3]) ==
> > true_regnum (operands[0])))"
> > + && (peep2_reg_dead_p (2, operands[0])
> > + || (true_regnum (operands[3]) == true_regnum (operands[0])))
> > + && !(optimize_size && satisfies_constraint_I (operands[4]))
> > + && !(optimize_size && satisfies_constraint_I (operands[5]))"
> > ;; the preparation statements take care to put proper operand in
> > operands[4]
> > ;; operands[4] will always contain the correct operand. This is added to
> > satisfy commutativity
> > [(set (match_dup 3)
> > @@ -6329,7 +6316,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
> > [(set (match_operand:SI 0 "register_operand" "=q,r,r")
> > (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")
> > (match_operand:SI 2 "_1_2_3_operand" ""))
> > - (match_operand:SI 3 "nonmemory_operand" "0,r,Cal")))]
> > + (match_operand:SI 3 "nonmemory_operand" "0,r,Csz")))]
> > ""
> > "add%2%?\\t%0,%3,%1"
> > [(set_attr "length" "*,4,8")
> > diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
> > index f9ef3f94dfe..abfeedffe9a 100644
> > --- a/gcc/config/arc/constraints.md
> > +++ b/gcc/config/arc/constraints.md
> > @@ -428,6 +428,12 @@
> > && !arc_legitimate_pic_addr_p (op)
> > && !satisfies_constraint_I (op)"))
> >
> > +(define_constraint "Csz"
> > + "a 32 bit constant avoided when compiling for size."
> > + (match_test "immediate_operand (op, VOIDmode)
> > + && !arc_legitimate_pic_addr_p (op)
> > + && !(satisfies_constraint_I (op) && optimize_size)"))
> > +
> > ; Note that the 'cryptic' register constraints will not make reload use the
> > ; associated class to reload into, but this will not penalize reloading of
> > any
> > ; other operands, or using an alternate part of the same alternative.
> > diff --git a/gcc/testsuite/gcc.target/arc/tph_addx.c
> > b/gcc/testsuite/gcc.target/arc/tph_addx.c
> > new file mode 100644
> > index 00000000000..f942ab19eb1
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/arc/tph_addx.c
> > @@ -0,0 +1,53 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-Os" } */
> > +
> > +/* when compiling for size avoid the following peephole
> > +-------------------------------------------------------------
> > +Pattern 1 : r0 = r1 << {i}
> > + r3 = r4/INT + r0 ;;and commutative
> > + ||
> > + \/
> > + add{i} r3,r4/INT,r1
> > +-------------------------------------------------------------
> > +*/
> > +
> > +typedef int a;
> > +typedef int b ;
> > +struct c
> > +{
> > + b d;
> > +};
> > +
> > +struct e
> > +{
> > + a f;
> > +};
> > +
> > +int g(int family)
> > +{
> > + switch (family)
> > + case 2:
> > + return sizeof(struct e);
> > + return 0;
> > +}
> > +
> > +int h(int family)
> > +{
> > + return 1 + g(family) - 1 ;
> > +}
> > +
> > +extern void m (void);
> > +
> > +int i(int j)
> > +{
> > + struct c *hdr;
> > + int k;
> > + int l;
> > + k = h(j);
> > + l = sizeof(struct c) + k * 2;
> > + hdr->d = l ;
> > + if (j)
> > + m();
> > +}
> > +
> > +/* { dg-final { scan-assembler-not "add\d" } } */
> > --
> > 2.17.1
> >