From: "Moore, Catherine" <Catherine_Moore@mentor.com>
To: Richard Sandiford <rdsandiford@googlemail.com>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
"Rozycki, Maciej" <Maciej_Rozycki@mentor.com>
Subject: RE: FW: [PATCH] [MIPS] microMIPS gcc support
Date: Wed, 20 Mar 2013 20:15:00 -0000 [thread overview]
Message-ID: <FD3DCEAC5B03E9408544A1E416F11242987BEADD@NA-MBX-01.mgc.mentorg.com> (raw)
In-Reply-To: <874ng7p1lr.fsf@talisman.default>
[-- Attachment #1: Type: text/plain, Size: 6767 bytes --]
> -----Original Message-----
> From: Richard Sandiford [mailto:rdsandiford@googlemail.com]
> Sent: Tuesday, March 19, 2013 4:38 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:
> >> -----Original Message-----
> >> From: Richard Sandiford [mailto:rdsandiford@googlemail.com]
> >> Sent: Tuesday, March 19, 2013 3:26 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:
> >> >> >> -----Original Message-----
> >> >> >> From: Richard Sandiford [mailto:rdsandiford@googlemail.com]
> >> >> >> Sent: Tuesday, March 05, 2013 4:06 PM
> >> >> >> To: Moore, Catherine
> >> >> >> Cc: gcc-patches@gcc.gnu.org; Rozycki, Maciej
> >> >> >> Subject: Re: FW: [PATCH] [MIPS] microMIPS gcc support:
> >> >> >>
> >> >> >> We have a few internal-only undocumented constraints that
> >> >> >> aren't used much, so we should be able to move them to the "Y"
> >> >> >> space
> >> instead.
> >> >> >> The patch below does this for "T" and "U". Then we could use "U"
> >> >> >> for new, longer constraints.
> >> >> >>
> >> >> >>
> >> >> >> U<type><factor><bits>
> >> >> >>
> >> >> >> where <type> is:
> >> >> >>
> >> >> >> s for signed
> >> >> >> u for unsigned
> >> >> >> d for decremented unsigned (-1 ... N)
> >> >> >> i for incremented unsigned (1 ... N)
> >> >> >>
> >> >> >> where <factor> is:
> >> >> >>
> >> >> >> b for "byte" (*1)
> >> >> >> h for "halfwords" (*2)
> >> >> >> w for "words" (*4)
> >> >> >> d for "doublewords" (*8) -- useful for 64-bit MIPS16 but probably
> not
> >> >> >> needed for 32-bit microMIPS
> >> >> >>
> >> >> >> and where <bits> is the number of bits. <type> and <factor>
> >> >> >> could be replaced with an ad-hoc two-letter combination for special
> cases.
> >> >> >> E.g. "Uas9" ("add stack") for ADDISUP.
> >> >> >>
> >> >> >> Just a suggestion though. I'm not saying these names are
> >> >> >> totally intuitive or anything, but they should at least be
> >> >> >> better than arbitrary
> >> >> letters.
> >> >> >>
> >> >> >> Also, <bits> could be two digits if necessary, or we could just
> >> >> >> use hex
> >> >> digits.
> >> >> >
> >> >> > I extended this proposal a bit by:
> >> >> > 1. Adding a <type> e for encoded. The constraint will start
> >> >> > with Ue, when the operand is an encoded value.
> >> >> > 2. I decided to use two digits for <bits>.
> >> >> > 3. The ad-hoc combination is used for anything else.
> >> >>
> >> >> First of all, thanks for coming up with a counter-suggestion. I'm
> >> >> hopeless at naming things, so I was hoping there would be at least
> >> >> some
> >> pushback.
> >> >>
> >> >> "e" for "encoded" sounds good. I'm less keen on the mixture of
> >> >> single- and double-digit widths though (single digit for some
> >> >> "Ue"s, double digits for other "U"s.) I think we should either:
> >> >>
> >> >> (a) use the same number of digits for all "U" constraints. That leaves
> >> >> one character for the "Ue" type, which isn't as mnemonic, but is in
> >> >> line with what we do elsewhere.
> >> >>
> >> >> (b) avoid digits in the "Ue" forms and just have an ad-hoc letter
> >> combination.
> >>
> >> FWIW, as far as this point goes, the patch still has "Uea4".
> >>
> >> >> > +/* Return true if X is a legitimate address that conforms to
> >> >> > +the
> >> >> requirements
> >> >> > + for any of the short microMIPS LOAD or STORE instructions
> >> >> > + except
> >> LWSP
> >> >> > + or SWSP. */
> >> >> > +
> >> >> > +bool
> >> >> > +umips_address_p (rtx x, bool load, enum machine_mode mode) {
> >> >> > +
> >> >> > + struct mips_address_info addr;
> >> >> > + bool ok = mips_classify_address (&addr, x, mode, false)
> >> >> > + && addr.type == ADDRESS_REG
> >> >> > + && M16_REG_P (REGNO (addr.reg))
> >> >> > + && CONST_INT_P (addr.offset);
> >> >> > +
> >> >> > + if (!ok)
> >> >> > + return false;
> >> >> > +
> >> >> > + if (mips_unsigned_immediate_p (INTVAL (addr.offset), 4, 2)
> >> >> > + || mips_unsigned_immediate_p (INTVAL (addr.offset), 4, 1))
> >> >> > + return true;
> >> >> > +
> >> >> > + if (load && IN_RANGE (INTVAL (addr.offset), -1, 14))
> >> >> > + return true;
> >> >> > +
> >> >> > + if (!load && IN_RANGE (INTVAL (addr.offset), 0, 15))
> >> >> > + return true;
> >> >> > +
> >> >> > + return false;
> >> >> > +
> >> >> > +}
> >> >>
> >> >> No blank lines after "{" and before "}".
> >> >>
> >> >> More importantly, what cases are these range tests covering?
> >> >> Both binutils and qemu seem to think that LW and SW need offsets
> >> >> that exactly match:
> >> >>
> >> >> mips_unsigned_immediate_p (INTVAL (addr.offset), 4, 2)
> >> >>
> >> >
> >> > Those range tests are for the LBU16 and SB16 instructions. LBU16
> >> > supports offsets from -1 to 14 (encodes -1 as 15) while the SB16
> >> > insn supports offsets from 0-15.
> >>
> >> They need to use separate constraints in that case. The patch as
> >> written allows -1 offsets for LW16 too. (In rare cases, offsets like
> >> -1 can be used even with aligned word loads.)
> >>
> >> E.g. we could have:
> >>
> >> /* Return true if X is legitimate for accessing values of mode MODE,
> >> if it is based on a MIPS16 register, and if the offset satisfies
> >> OFFSET_PREDICATE. */
> >>
> >> bool
> >> m16_based_address_p (rtx x, enum machine_mode mode,
> >> insn_operand_predicate_fn predicate) {
> >> struct mips_address_info addr;
> >> return (mips_classify_address (&addr, x, mode, false)
> >> && addr.type == ADDRESS_REG
> >> && M16_REG_P (REGNO (addr.reg))
> >> && offset_predicate (addr.offset)); }
> >>
> >> Perhaps if there are so many of these, we should define "T???" to be
> >> a memory constraint in which the base register is an M16_REG and in
> >> which "???" has the same format as for "U". E.g. "Tuw4" for LW and SW.
> >> That's just a suggestion though.
> >>
> >
> > I'd just as soon leave them as "Z" constraints, if that's okay with you.
>
> Yeah, that's fine.
>
> > I do see the need for separate constraints. I'll fix that up.
> > Adding the new microMIPS memory constraints here would take ZS-ZZ.
> > The base microMIPS patch used ZC and ZD and ZR has been used.
> > That leaves ZA, ZB, and ZD to ZQ.
>
> Sounds good, thanks.
>
HI Richard,
Now done. New patch and ChangeLog attached. Thanks for reviewing.
Catherine
[-- Attachment #2: short-delay.cl --]
[-- Type: application/octet-stream, Size: 1662 bytes --]
2013-03-20 Catherine Moore <clm@codesourcery.com>
* config/mips/constraints.md (u, Udb7, Uead, Uean, Ueim, Uib3,
Uesp, Usb3, ZS, ZT, ZU, ZV, ZW, ZX, ZY, ZZ): New constraints.
* config/mips/predicates.md (lwsp_swsp_operand, lw16_operand,
lhu16_operand, lbu16_operand, sw16_operand, sh16_operand,
sb16_operand, db4_operand, db7_operand, ib3_operand,
sb3_operand, ub4_operand, uh4_operand, uw4_operand,
uw5_operand, addiur1sp_operand, addiur2_operand,
addiusp_operand, andi16_operand): New predicates.
* config/mips/mips.md (compression): New attribute.
(enabled): New attribute.
(length): Consider compression in computing length.
(shift_compression): New code attribute.
(*add<mode>3): New operands. Record compression.
(sub<mode>3): Likewise.
(one_cmpl<mode>2): Likewise.
(*and<mode>3): Likewise.
(*ior<mode>3): Likewise.
(unnamed pattern for xor): Likewise.
(*zero_extend<SHORT:mode><GPR:mode>2): Likewise.
(*<optab><mode>3): Likewise.
(*mov<mode>_internal: Likewise.
* config/mips/mips-protos.h (mips_signed_immediate_p): New.
(mips_unsigned_immediate_p): New.
(umips_lwsp_swsp_address_p): New.
(m16_based_address_p): New.
* config/mips/mips-protos.h (mips_signed_immediate_p): New prototype.
(mips_unsigned_immediate_p): New prototype.
(lwsp_swsp_address_p): New prototype.
(m16_based_address_p): New prototype.
* config/mips/mips.c (mips_unsigned_immediate_p): New function.
(mips_signed_immediate_p): New function.
(m16_based_address_p): New function.
(lwsp_swsp_address_p): New function.
(mips_print_operand_punctuation): Recognize short delay slot insns
for microMIPS.add<mode>3"
[-- Attachment #3: short-delay.patch --]
[-- Type: application/octet-stream, Size: 18810 bytes --]
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"))
+
+(define_constraint "Uean"
+ "@internal
+ A microMIPS encoded andi operand."
+ (match_operand 0 "andi16_operand" ""))
+
+(define_constraint "Ueim"
+ "@internal
+ A microMIPS encoded ADDIUSP operand."
+ (match_operand 0 "addiusp_operand" ""))
+
+(define_constraint "Uib3"
+ "@internal
+ An unsigned, incremented three-bit constant."
+ (match_operand 0 "ib3_operand"))
+
+(define_constraint "Uesp"
+ "@internal
+ A microMIPS encoded ADDIUR1SP operand."
+ (match_operand 0 "addiur1sp_operand" ""))
+
+(define_constraint "Usb3"
+ "@internal
+ A signed three-bit constant."
+ (match_operand 0 "sb3_operand"))
+
(define_memory_constraint "W"
"@internal
A memory address based on a member of @code{BASE_REG_CLASS}. This is
@@ -257,3 +295,21 @@
"@internal
An address valid for loading/storing register exclusive"
(match_operand 0 "mem_noofs_operand"))
+
+(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")))
Index: gcc/config/mips/predicates.md
===================================================================
--- gcc/config/mips/predicates.md (revision 196638)
+++ gcc/config/mips/predicates.md (working copy)
@@ -122,6 +122,81 @@
? M16_REG_P (REGNO (op))
: GP_REG_P (REGNO (op))")))
+(define_predicate "umips_lwsp_swsp_operand"
+ (and (match_code "mem")
+ (match_test "umips_lwsp_swsp_address_p (XEXP (op, 0), mode)")))
+
+(define_predicate "umips_load_operand"
+ (and (match_code "mem")
+ (match_test "umips_load_store_address_p (XEXP (op, 0), true, mode)")))
+
+(define_predicate "umips_store_operand"
+ (and (match_code "mem")
+ (match_test "umips_load_store_address_p (XEXP (op, 0), false, mode)")))
+
+(define_predicate "db4_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op) - 1, 4, 0)")))
+
+(define_predicate "db7_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op) + 1, 7, 0)")))
+
+(define_predicate "ib3_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op) - 1, 3, 0)")))
+
+(define_predicate "sb3_operand"
+ (and (match_code "const_int")
+ (match_test "mips_signed_immediate_p (INTVAL (op), 3, 0)")))
+
+(define_predicate "ub4_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op), 4, 0)")))
+
+(define_predicate "uh4_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op), 4, 1)")))
+
+(define_predicate "uw4_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op), 4, 2)")))
+
+(define_predicate "uw5_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op), 5, 2)")))
+
+(define_predicate "addiur1sp_operand"
+ (and (match_code "const_int")
+ (match_test "mips_unsigned_immediate_p (INTVAL (op), 8, 2)")))
+
+(define_predicate "addiur2_operand"
+ (and (match_code "const_int")
+ (ior (match_test "INTVAL (op) == -1")
+ (match_test "INTVAL (op) == 1")
+ (match_test "INTVAL (op) == 4")
+ (match_test "INTVAL (op) == 8")
+ (match_test "INTVAL (op) == 12")
+ (match_test "INTVAL (op) == 16")
+ (match_test "INTVAL (op) == 20")
+ (match_test "INTVAL (op) == 24"))))
+
+(define_predicate "addiusp_operand"
+ (and (match_code "const_int")
+ (ior (match_test "(IN_RANGE (INTVAL (op), 2, 257))")
+ (match_test "(IN_RANGE (INTVAL (op), -258, -3))"))))
+
+(define_predicate "andi16_operand"
+ (and (match_code "const_int")
+ (ior (match_test "IN_RANGE (INTVAL (op), 1, 4)")
+ (match_test "IN_RANGE (INTVAL (op), 7, 8)")
+ (match_test "IN_RANGE (INTVAL (op), 15, 16)")
+ (match_test "IN_RANGE (INTVAL (op), 31, 32)")
+ (match_test "IN_RANGE (INTVAL (op), 63, 64)")
+ (match_test "INTVAL (op) == 255")
+ (match_test "INTVAL (op) == 32768")
+ (match_test "INTVAL (op) == 65535"))))
+
(define_predicate "movep_src_register"
(and (match_code "reg")
(ior (match_test ("IN_RANGE (REGNO (op), 2, 3)"))
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md (revision 196638)
+++ gcc/config/mips/mips.md (working copy)
@@ -412,12 +412,28 @@
(const_string "yes")
(const_string "no")))
+(define_attr "compression" "none,all,micromips"
+ (const_string "none"))
+
+(define_attr "enabled" "no,yes"
+ (if_then_else (ior (eq_attr "compression" "all,none")
+ (and (eq_attr "compression" "micromips")
+ (match_test "TARGET_MICROMIPS")))
+ (const_string "yes")
+ (const_string "no")))
+
;; Length of instruction in bytes.
(define_attr "length" ""
(cond [(and (eq_attr "extended_mips16" "yes")
(match_test "TARGET_MIPS16"))
(const_int 8)
+ (and (ior (eq_attr "compression" "micromips")
+ (eq_attr "compression" "all"))
+ (eq_attr "dword_mode" "no")
+ (match_test "TARGET_MICROMIPS"))
+ (const_int 2)
+
;; Direct microMIPS branch instructions have a range of
;; [-0x10000,0xfffe], otherwise the range is [-0x20000,0x1fffc].
;; If a branch is outside this range, we have a choice of two
@@ -964,6 +980,10 @@
(xor "xori")
(and "andi")])
+(define_code_attr shift_compression [(ashift "micromips")
+ (lshiftrt "micromips")
+ (ashiftrt "none")])
+
;; <fcond> is the c.cond.fmt condition associated with a particular code.
(define_code_attr fcond [(unordered "un")
(uneq "ueq")
@@ -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")))]
"!TARGET_MIPS16"
- "@
- <d>addu\t%0,%1,%2
- <d>addiu\t%0,%1,%2"
+{
+ if (which_alternative == 0
+ || which_alternative == 1)
+ return "<d>addu\t%0,%1,%2";
+ else
+ return "<d>addiu\t%0,%1,%2";
+}
[(set_attr "alu_type" "add")
+ (set_attr "compression" "micromips,*,micromips,micromips,micromips,micromips,*")
(set_attr "mode" "<MODE>")])
(define_insn "*add<mode>3_mips16"
@@ -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"; }
[(set_attr "alu_type" "sub")
+ (set_attr "compression" "micromips,*")
(set_attr "mode" "<MODE>")])
(define_insn "*subsi3_extended"
@@ -2828,8 +2854,8 @@
(set_attr "mode" "<UNITMODE>")])
(define_insn "one_cmpl<mode>2"
- [(set (match_operand:GPR 0 "register_operand" "=d")
- (not:GPR (match_operand:GPR 1 "register_operand" "d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=!u,d")
+ (not:GPR (match_operand:GPR 1 "register_operand" "!u,d")))]
""
{
if (TARGET_MIPS16)
@@ -2838,6 +2864,7 @@
return "nor\t%0,%.,%1";
}
[(set_attr "alu_type" "not")
+ (set_attr "compression" "micromips,*")
(set_attr "mode" "<MODE>")])
\f
;;
@@ -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>")])
(define_insn "*and<mode>3_mips16"
@@ -2952,14 +2982,16 @@
})
(define_insn "*ior<mode>3"
- [(set (match_operand:GPR 0 "register_operand" "=d,d")
- (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d")
- (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
+ [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
+ (ior:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
+ (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
"!TARGET_MIPS16"
"@
or\t%0,%1,%2
+ or\t%0,%1,%2
ori\t%0,%1,%x2"
[(set_attr "alu_type" "or")
+ (set_attr "compression" "micromips,*,*")
(set_attr "mode" "<MODE>")])
(define_insn "*ior<mode>3_mips16"
@@ -2979,14 +3011,16 @@
"")
(define_insn ""
- [(set (match_operand:GPR 0 "register_operand" "=d,d")
- (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d")
- (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
+ [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
+ (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
+ (match_operand:GPR 2 "uns_arith_operand" "!u,d,K")))]
"!TARGET_MIPS16"
"@
xor\t%0,%1,%2
+ xor\t%0,%1,%2
xori\t%0,%1,%x2"
[(set_attr "alu_type" "xor")
+ (set_attr "compression" "micromips,*,*")
(set_attr "mode" "<MODE>")])
(define_insn ""
@@ -3162,14 +3196,16 @@
})
(define_insn "*zero_extend<SHORT:mode><GPR:mode>2"
- [(set (match_operand:GPR 0 "register_operand" "=d,d")
+ [(set (match_operand:GPR 0 "register_operand" "=!u,d,d")
(zero_extend:GPR
- (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))]
+ (match_operand:SHORT 1 "nonimmediate_operand" "!u,d,m")))]
"!TARGET_MIPS16"
"@
andi\t%0,%1,<SHORT:mask>
+ andi\t%0,%1,<SHORT:mask>
l<SHORT:size>u\t%0,%1"
- [(set_attr "move_type" "andi,load")
+ [(set_attr "move_type" "andi,andi,load")
+ (set_attr "compression" "micromips,*,*")
(set_attr "mode" "<GPR:MODE>")])
(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e"
@@ -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"))]
"!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,fpload,mfc,fpstore,mfc,mtc,mtlo,mflo,mtc,fpload,mfc,fpstore")
+ (set_attr "compression" "all,micromips,*,*,micromips,micromips,micromips,*,micromips,micromips,*,*,*,*,*,*,*,*,*,*,*,*,*")
(set_attr "mode" "SI")])
(define_insn "*mov<mode>_mips16"
@@ -5225,9 +5262,9 @@
})
(define_insn "*<optab><mode>3"
- [(set (match_operand:GPR 0 "register_operand" "=d")
- (any_shift:GPR (match_operand:GPR 1 "register_operand" "d")
- (match_operand:SI 2 "arith_operand" "dI")))]
+ [(set (match_operand:GPR 0 "register_operand" "=!u,d")
+ (any_shift:GPR (match_operand:GPR 1 "register_operand" "!u,d")
+ (match_operand:SI 2 "arith_operand" "Uib3,dI")))]
"!TARGET_MIPS16"
{
if (CONST_INT_P (operands[2]))
@@ -5237,6 +5274,7 @@
return "<d><insn>\t%0,%1,%2";
}
[(set_attr "type" "shift")
+ (set_attr "compression" "<shift_compression>,none")
(set_attr "mode" "<MODE>")])
(define_insn "*<optab>si3_extend"
Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h (revision 196638)
+++ gcc/config/mips/mips-protos.h (working copy)
@@ -350,12 +350,19 @@
extern void mips_expand_vec_minmax (rtx, rtx, rtx,
rtx (*) (rtx, rtx, rtx), bool);
+extern bool mips_signed_immediate_p (unsigned HOST_WIDE_INT, int, int);
+extern bool mips_unsigned_immediate_p (unsigned HOST_WIDE_INT, int, int);
+
extern const char *umips_output_save_restore (bool, rtx);
extern bool umips_save_restore_pattern_p (bool, rtx);
extern bool umips_load_store_pair_p (bool, rtx *);
extern void umips_output_load_store_pair (bool, rtx *);
extern bool umips_movep_target_p (rtx, rtx);
+
+extern bool umips_lwsp_swsp_address_p (rtx, enum machine_mode);
+extern bool umips_load_store_address_p (rtx, bool, enum machine_mode);
extern bool umips_12bit_offset_address_p (rtx, enum machine_mode);
+
extern rtx mips_expand_thread_pointer (rtx);
extern bool mips_eh_uses (unsigned int);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c (revision 196638)
+++ gcc/config/mips/mips.c (working copy)
@@ -2377,6 +2377,81 @@
return 0;
}
+/* Return true if X fits within an unsigned field of BITS bits that is
+ shifted left SHIFT bits before being used. */
+
+bool
+mips_unsigned_immediate_p (unsigned HOST_WIDE_INT x, int bits, int shift = 0)
+{
+ return (x & ((1 << shift) - 1)) == 0 && x < (1 << (shift + bits));
+}
+
+/* Return true if X fits within a signed field of BITS bits that is
+ shifted left SHIFT bits before being used. */
+
+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);
+}
+
+/* Return true if X is a legitimate address that conforms to the requirements
+ for any of the short microMIPS LOAD or STORE instructions except LWSP
+ or SWSP. */
+
+bool
+umips_load_store_address_p (rtx x, bool load, enum machine_mode mode)
+{
+ struct mips_address_info addr;
+ bool ok = mips_classify_address (&addr, x, mode, false)
+ && addr.type == ADDRESS_REG
+ && M16_REG_P (REGNO (addr.reg))
+ && CONST_INT_P (addr.offset);
+
+ if (!ok)
+ return false;
+
+ /* 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);
+
+#if 0
+ if (mips_unsigned_immediate_p (INTVAL (addr.offset), 4, 2)
+ || mips_unsigned_immediate_p (INTVAL (addr.offset), 4, 1))
+ return true;
+
+ if (load && IN_RANGE (INTVAL (addr.offset), -1, 14))
+ return true;
+
+ if (!load && IN_RANGE (INTVAL (addr.offset), 0, 15))
+ return true;
+#endif
+ return false;
+}
+
+/* Return true if X is a legitimate address that conforms to the requirements
+ for a microMIPS LWSP or SWSP insn. */
+
+bool
+umips_lwsp_swsp_address_p (rtx x, enum machine_mode mode)
+{
+ struct mips_address_info addr;
+
+ return (mips_classify_address (&addr, x, mode, false)
+ && addr.type == ADDRESS_REG
+ && REGNO (addr.reg) == STACK_POINTER_REGNUM
+ && uw5_operand (addr.offset, mode));
+}
+
/* Return true if X is a legitimate address with a 12-bit offset.
MODE is the mode of the value being accessed. */
@@ -8009,9 +8084,10 @@
break;
case '!':
- /* When final_sequence is 0, the delay slot will be a nop. We can
- a 16-bit delay slot for microMIPS. */
- if (final_sequence == 0)
+ /* If the delay slot instruction is short, then use the
+ compact version. */
+ if (final_sequence == 0
+ || get_attr_length (XVECEXP (final_sequence, 0, 1)) == 2)
putc ('s', file);
break;
next prev parent reply other threads:[~2013-03-20 20:15 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <FD3DCEAC5B03E9408544A1E416F1124211F9CC2E@NA-MBX-04.mgc.mentorg.com>
2012-07-19 18:51 ` Moore, Catherine
2012-07-20 0:46 ` Richard Sandiford
2013-01-22 20:23 ` Moore, Catherine
2013-01-22 20:27 ` Moore, Catherine
2013-01-23 20:05 ` Richard Sandiford
2013-01-26 3:52 ` Maciej W. Rozycki
2013-01-26 10:17 ` Richard Sandiford
2013-01-27 13:58 ` Maciej W. Rozycki
2013-01-28 10:14 ` Richard Sandiford
2013-02-12 19:00 ` Moore, Catherine
2013-02-13 11:43 ` Richard Sandiford
2013-02-19 16:31 ` Moore, Catherine
2013-02-19 18:25 ` Richard Sandiford
2013-02-19 22:27 ` Maciej W. Rozycki
2013-02-21 2:28 ` Moore, Catherine
2013-02-21 21:20 ` Richard Sandiford
2013-02-24 23:52 ` Moore, Catherine
2013-02-25 9:41 ` Richard Sandiford
2013-02-25 13:55 ` Moore, Catherine
2013-03-04 19:43 ` Moore, Catherine
2013-03-04 20:54 ` Richard Sandiford
2013-03-04 22:47 ` Moore, Catherine
2013-03-05 21:06 ` Richard Sandiford
2013-03-13 20:30 ` Moore, Catherine
2013-03-14 20:55 ` Richard Sandiford
2013-03-15 18:00 ` Moore, Catherine
2013-03-19 19:26 ` Richard Sandiford
2013-03-19 21:23 ` Moore, Catherine
2013-03-19 21:23 ` Richard Sandiford
2013-03-20 20:15 ` Moore, Catherine [this message]
2013-03-20 21:48 ` Richard Sandiford
2013-03-20 22:02 ` Moore, Catherine
2013-03-21 8:05 ` Richard Sandiford
2013-03-21 23:04 ` Moore, Catherine
2013-03-22 0:05 ` Richard Sandiford
2013-03-22 18:31 ` Moore, Catherine
2013-03-23 9:07 ` Richard Sandiford
2013-04-12 18:38 ` Many warnings in MIPS port (Was: [PATCH] [MIPS] microMIPS gcc support) David Daney
2013-04-12 20:35 ` Maciej W. Rozycki
2013-04-12 22:08 ` Moore, Catherine
2013-04-13 6:36 ` David Daney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=FD3DCEAC5B03E9408544A1E416F11242987BEADD@NA-MBX-01.mgc.mentorg.com \
--to=catherine_moore@mentor.com \
--cc=Maciej_Rozycki@mentor.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=rdsandiford@googlemail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).