FW: [PATCH] [MIPS] microMIPS gcc support

Moore, Catherine Catherine_Moore@mentor.com
Wed Mar 20 22:02:00 GMT 2013


Hi Richard,
I'm sorry for wasting your time.  I accidentally posted an older version of the patch earlier this afternoon.
This is the version that I meant to post and is hopefully a lot closer to what you are looking for.
I named some of the predicates/constraints differently than your current suggestions, but hopefully they will be OK.
Thanks,
Catherine


> -----Original Message-----
> From: Richard Sandiford [mailto:rdsandiford@googlemail.com]
> Sent: Wednesday, March 20, 2013 5:48 PM
> To: Moore, Catherine
> Cc: gcc-patches@gcc.gnu.org; Rozycki, Maciej
> Subject: Re: FW: [PATCH] [MIPS] microMIPS gcc support
> 
> "Moore, Catherine" <Catherine_Moore@mentor.com> writes:
> > Index: gcc/config/mips/constraints.md
> >
> ==========================================================
> =========
> > --- gcc/config/mips/constraints.md	(revision 196638)
> > +++ gcc/config/mips/constraints.md	(working copy)
> > @@ -43,6 +43,9 @@
> >  (define_register_constraint "b" "ALL_REGS"
> >    "@internal")
> >
> > +(define_register_constraint "u" "M16_REGS"
> > +  "@internal")
> > +
> >  ;; MIPS16 code always calls through a MIPS16 register; see
> > mips_emit_call_insn  ;; for details.
> >  (define_register_constraint "c" "TARGET_MIPS16 ? M16_REGS @@ -170,6
> > +173,41 @@
> >    (and (match_operand 0 "call_insn_operand")
> >         (match_test "CONSTANT_P (op)")))
> >
> > +(define_constraint "Udb7"
> > +  "@internal
> > +   A decremented unsigned constant of 7 bits."
> > +  (match_operand 0 "db7_operand"))
> > +
> > +(define_constraint "Uea4"
> > +  "@internal
> > +   A microMIPS encoded ADDIUR2 immediate operand."
> > +  (match_operand 0 "addiur2_operand"))
> 
> I'm still wary of having digits for some "Ue"s and not others, especially
> because (as I understand it) ADDIUR2 takes a 3-bit rather than 4-bit operand.
> How about "Ueau" here (= add of "u" register).
> For consistency...
> 
> > +(define_constraint "Ueim"
> > +  "@internal
> > +   A microMIPS encoded ADDIUSP operand."
> > +  (match_operand 0 "addiusp_operand" ""))
> 
> ...this could be "Ueas" (= add of stack register).  Redundant "".
> 
> > +(define_constraint "Uesp"
> > +  "@internal
> > +   A microMIPS encoded ADDIUR1SP operand."
> > +  (match_operand 0 "addiur1sp_operand" ""))
> 
> This is "6 bits zero extended and shifted left twice", so the constraint should
> be "Uuw6" and the predicate should be "uw6_operand".  Redundant "".
> 
> > +(define_memory_constraint "ZS"
> > +  "@internal
> > +   A microMIPS memory operand for use with the LWSP/SWSP insns."
> > +  (and (match_code "mem")
> > +       (match_operand 0 "umips_lwsp_swsp_operand")))
> > +
> > +(define_memory_constraint "ZT"
> > +  "@internal
> > +   A microMIPS memory operand for use with the various LOAD insns."
> > +  (and (match_code "mem")
> > +       (match_operand 0 "umips_load_operand")))
> > +
> > +(define_memory_constraint "ZU"
> > +  "@internal
> > +   A microMIPS memory operand for use with the various STORE insns."
> > +  (and (match_code "mem")
> > +       (match_operand 0 "umips_store_operand")))
> 
> As I mentioned before, we need a separate predicate and constraint for each
> range.  We can't have things like:
> 
> > +  /* For the LBU16 insn.  */
> > +  if (load && db4_operand (addr.offset, mode))
> > +    return true;
> > +
> > +  /* For the SB16 insn.  */
> > +  if (!load && ub4_operand (addr.offset, mode))
> > +    return true;
> > +
> > +  /* For SH16, LHU16, SW16 and LW16 insns.  */  return uw4_operand
> > + (addr.offset, mode)
> > +          || uh4_operand (addr.offset, mode);
> 
> because this allows SH16 to be ub4_operand, uw4_operand or uh4_operand,
> and so on.  There needs to be one predicate/constraint pair for
> ub4_operands, one for db4_operands, one for uw4_operands and one for
> uh4_operands.
> 
> Please use the function I suggested in my previous reply, in which the offset
> predicate is passed in as a function pointer.
> 
> > @@ -1131,14 +1151,19 @@
> >    "")
> >
> >  (define_insn "*add<mode>3"
> > -  [(set (match_operand:GPR 0 "register_operand" "=d,d")
> > -	(plus:GPR (match_operand:GPR 1 "register_operand" "d,d")
> > -		  (match_operand:GPR 2 "arith_operand" "d,Q")))]
> > +  [(set (match_operand:GPR 0 "register_operand" "=!u,d,!u,!ks,d,d,d")
> > +	(plus:GPR (match_operand:GPR 1 "register_operand"
> "!u,d,!u,0,!ks,!ks,d")
> > +		  (match_operand:GPR 2 "arith_operand"
> > +"!u,d,Uea4,Usb3,Ueim,Uesp,Q")))]
> 
> Hmm, not sure about these alternatives.  Two have the form d/ks/U...
> (the last two) and I'm not sure which instruction Usb3 corresponds to.
> 
> My guess from the manual would be:
> 
>   [(set (match_operand:GPR 0 "register_operand" "=!u,d,!u,!u,!ks,!d,d")
> 	(plus:GPR (match_operand:GPR 1 "register_operand"
> "!u,d,!u,!ks,!ks,0,d")
> 		  (match_operand:GPR 2 "arith_operand"
> 		     "!u,d,Ueau,Uuw6,Ueas,Usb4,Q")))]
> 
> > @@ -1347,12 +1372,13 @@
> >     (set_attr "mode" "<UNITMODE>")])
> >
> >  (define_insn "sub<mode>3"
> > -  [(set (match_operand:GPR 0 "register_operand" "=d")
> > -	(minus:GPR (match_operand:GPR 1 "register_operand" "d")
> > -		   (match_operand:GPR 2 "register_operand" "d")))]
> > +  [(set (match_operand:GPR 0 "register_operand" "=!u,d")
> > +	(minus:GPR (match_operand:GPR 1 "register_operand" "!u,d")
> > +		   (match_operand:GPR 2 "register_operand" "!u,d")))]
> >    ""
> > -  "<d>subu\t%0,%1,%2"
> > +{ return "<d>subu\t%0,%1,%2"; }
> 
> The change to the last line shouldn't be needed.  (Plain "..."
> is better than { return "...."; } where possible, because the generator doesn't
> need to create a separate output function.)
> 
> > @@ -2878,9 +2905,9 @@
> >  ;;  register =op1                      x
> >
> >  (define_insn "*and<mode>3"
> > -  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d,d")
> > -	(and:GPR (match_operand:GPR 1 "nonimmediate_operand"
> "o,o,W,d,d,d,d")
> > -		 (match_operand:GPR 2 "and_operand"
> "Yb,Yh,Yw,K,Yx,Yw,d")))]
> > +  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
> > +	(and:GPR (match_operand:GPR 1 "nonimmediate_operand"
> "o,o,W,!u,d,d,d,0,d")
> > +		 (match_operand:GPR 2 "and_operand"
> > +"Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
> >    "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1],
> operands[2])"
> >  {
> >    int len;
> > @@ -2897,20 +2924,23 @@
> >        operands[1] = gen_lowpart (SImode, operands[1]);
> >        return "lwu\t%0,%1";
> >      case 3:
> > +    case 4:
> >        return "andi\t%0,%1,%x2";
> > -    case 4:
> > +    case 5:
> >        len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
> >        operands[2] = GEN_INT (len);
> >        return "<d>ext\t%0,%1,0,%2";
> > -    case 5:
> > +    case 6:
> >        return "#";
> > -    case 6:
> > +    case 7:
> > +    case 8:
> >        return "and\t%0,%1,%2";
> >      default:
> >        gcc_unreachable ();
> >      }
> >  }
> > -  [(set_attr "move_type"
> > "load,load,load,andi,ext_ins,shift_shift,logical")
> > +  [(set_attr "move_type"
> "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
> > +   (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
> >     (set_attr "mode" "<MODE>")])
> 
> Looks good.
> 
> > @@ -4362,13 +4398,14 @@
> >  ;; in FP registers (off by default, use -mdebugh to enable).
> >
> >  (define_insn "*mov<mode>_internal"
> > -  [(set (match_operand:IMOVE32 0 "nonimmediate_operand"
> "=d,d,e,d,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m")
> > -	(match_operand:IMOVE32 1 "move_operand"
> "d,Yd,Yf,m,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))]
> > +  [(set (match_operand:IMOVE32 0 "nonimmediate_operand"
> "=d,!u,d,e,!u,!u,d,d,ZS,ZU,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*
> m")
> > +	(match_operand:IMOVE32 1 "move_operand"
> > +"d,J,Yd,Yf,Udb7,ZT,ZS,m,ks,!u,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B
> > +*C*D,*B*C*D"))]
> 
> The d <- ZS alternative (the 7th) should be !ks <- ZS instead.
> 
> >    "!TARGET_MIPS16
> >     && (register_operand (operands[0], <MODE>mode)
> >         || reg_or_0_operand (operands[1], <MODE>mode))"
> >    { return mips_output_move (operands[0], operands[1]); }
> > -  [(set_attr "move_type"
> > "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,
> > mtc,fpload,mfc,fpstore")
> > +  [(set_attr "move_type"
> > + "move,move,const,const,load,load,load,load,store,store,store,mtc,fpl
> > + oad,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore")
> 
> I think the 5th alternative (!u <- Udb7) should be "const" rather than "load".
> 
> > +/* Return true if X fits within a signed field of  BITS bits that is
> > +   shifted left SHIFT bits before being used.  */
> 
> Too many spaces before "BITS".
> 
> > +
> > +bool
> > +mips_signed_immediate_p (unsigned HOST_WIDE_INT x, int bits, int
> > +shift = 0) {  x += 1 << (bits + shift - 1);  return
> > +mips_unsigned_immediate_p (x, bits, shift); }
> 
> Formatting: there should be one extra space of indentantion.
> 
> Richard
-------------- next part --------------
A non-text attachment was scrubbed...
Name: short-delay-03.20.patch
Type: application/octet-stream
Size: 19613 bytes
Desc: short-delay-03.20.patch
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20130320/ccb11bd9/attachment.obj>


More information about the Gcc-patches mailing list