constraints.md (u, [...]): New constraints.
authorCatherine Moore <clm@codesourcery.com>
Mon, 25 Mar 2013 13:53:53 +0000 (09:53 -0400)
committerCatherine Moore <clm@gcc.gnu.org>
Mon, 25 Mar 2013 13:53:53 +0000 (09:53 -0400)
2013-03-25  Catherine Moore  <clm@codesourcery.com>

* config/mips/constraints.md (u, Udb7 Uead, Uean, Uesp, Uib3,
Uuw6, Usb4, ZS, ZT, ZU, ZV, ZW): New constraints.
* config/mip/predicates.md (lwsp_swsp_operand,
lw16_sw16_operand, lhu16_sh16_operand, lbu16_operand,
sb16_operand, db4_operand, db7_operand, ib3_operand,
sb4_operand, ub4_operand, uh4_operand, uw4_operand,
uw5_operand, uw6_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"

From-SVN: r197042

gcc/ChangeLog
gcc/config/mips/constraints.md
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/config/mips/predicates.md

index 491937cb2480f0cc567f2b8eb2ee2f1090c6bf11..c211bea081e3bd3341e9dc148cdafc9ffb187b82 100644 (file)
@@ -1,3 +1,41 @@
+2013-03-25  Catherine Moore  <clm@codesourcery.com>
+
+       * config/mips/constraints.md (u, Udb7 Uead, Uean, Uesp, Uib3,
+       Uuw6, Usb4, ZS, ZT, ZU, ZV, ZW): New constraints.
+       * config/mip/predicates.md (lwsp_swsp_operand,
+       lw16_sw16_operand, lhu16_sh16_operand, lbu16_operand,
+       sb16_operand, db4_operand, db7_operand, ib3_operand,
+       sb4_operand, ub4_operand, uh4_operand, uw4_operand,
+       uw5_operand, uw6_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"
+
 2013-03-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
        PR target/56720
        * config/arm/iterators.md (v_cmp_result): New mode attribute.
index 773ef3a71e61c31b65913ac55d9cc22d91dff82b..e73c440e1f41b9efd3442382453ae7d348127e69 100644 (file)
@@ -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
   (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 "Uead"
+  "@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 "Uesp"
+  "@internal
+   A microMIPS encoded ADDIUSP operand."
+  (match_operand 0 "addiusp_operand"))
+
+(define_constraint "Uib3"
+  "@internal
+   An unsigned, incremented constant of 3 bits."
+  (match_operand 0 "ib3_operand"))
+
+(define_constraint "Uuw6"
+  "@internal
+   An unsigned constant of 6 bits, shifted left two places."
+  (match_operand 0 "uw6_operand"))
+
+(define_constraint "Usb4"
+  "@internal
+   A signed constant of 4 bits."
+  (match_operand 0 "sb4_operand"))
+
 (define_memory_constraint "W"
   "@internal
    A memory address based on a member of @code{BASE_REG_CLASS}.  This is
  "@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 "lwsp_swsp_operand")))
+
+(define_memory_constraint "ZT"
+  "@internal
+   A microMIPS memory operand for use with the LW16/SW16 insns."
+  (and (match_code "mem")
+       (match_operand 0 "lw16_sw16_operand")))
+
+(define_memory_constraint "ZU"
+  "@internal
+   A microMIPS memory operand for use with the LHU16/SH16 insns."
+  (and (match_code "mem")
+       (match_operand 0 "lhu16_sh16_operand")))
+
+(define_memory_constraint "ZV"
+  "@internal
+   A microMIPS memory operand for use with the SB16 insn."
+  (and (match_code "mem")
+       (match_operand 0 "sb16_operand")))
+
+(define_memory_constraint "ZW"
+  "@internal
+   A microMIPS memory operand for use with the LBU16 insn."
+  (and (match_code "mem")
+       (match_operand 0 "lbu16_operand")))
+
index 2d03f5a0656d4af648a2e7e1e9019666d18d80ea..3aaf69a7804edc100b0d7ad5f56bff72de806cd5 100644 (file)
@@ -350,12 +350,17 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx));
 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_12bit_offset_address_p (rtx, enum machine_mode);
+extern bool lwsp_swsp_address_p (rtx, enum machine_mode);
+extern bool m16_based_address_p (rtx, enum machine_mode,
+                                int (*)(rtx_def*, machine_mode)); 
 extern rtx mips_expand_thread_pointer (rtx);
 
 extern bool mips_eh_uses (unsigned int);
index e4ab271fd60974519fa1e80b596cb2add40c7027..4957a150078ac7f1706ff6bdf438d93a432cb6fb 100644 (file)
@@ -2377,6 +2377,55 @@ mips_address_insns (rtx x, enum machine_mode mode, bool might_split_p)
   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 < ((unsigned) 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 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 offset_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, mode));
+}
+
+/* Return true if X is a legitimate address that conforms to the requirements
+   for a microMIPS LWSP or SWSP insn.  */
+
+bool
+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 +8058,10 @@ mips_print_operand_punctuation (FILE *file, int ch)
       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;
 
index d8de3405fa16a3dd1c4d9282df4c3eee0f1cb2fe..2f629107a57006a5e66b46ee70178216ee0547e4 100644 (file)
                (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 (eq_attr "compression" "micromips,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
                                  (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")
   "")
 
 (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,!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,Uead,Uuw6,Uesp,Usb4,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"
    (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"
   [(set_attr "alu_type" "sub")
+   (set_attr "compression" "micromips,*")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*subsi3_extended"
    (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)
     return "nor\t%0,%.,%1";
 }
   [(set_attr "alu_type" "not")
+   (set_attr "compression" "micromips,*")
    (set_attr "mode" "<MODE>")])
 \f
 ;;
 ;;  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;
       operands[1] = gen_lowpart (SImode, operands[1]);
       return "lwu\t%0,%1";
     case 3:
-      return "andi\t%0,%1,%x2";
     case 4:
+      return "andi\t%0,%1,%x2";
+    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:
-      return "#";
     case 6:
+      return "#";
+    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"
 })
 
 (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"
   "")
 
 (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 ""
 })
 
 (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"
 ;; 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,!u,d,e,!u,!ks,d,ZS,ZT,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,Udb7,Yd,Yf,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,const,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"
 })
 
 (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]))
   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 c6d7707093ee3e70cb4763cd6d1179113f35ba6a..57996fa8960f1cb06e44b26d79ac3a89d065e96b 100644 (file)
                    ? M16_REG_P (REGNO (op))
                    : GP_REG_P (REGNO (op))")))
 
+(define_predicate "lwsp_swsp_operand"
+  (and (match_code "mem")
+       (match_test "lwsp_swsp_address_p (XEXP (op, 0), mode)")))
+
+(define_predicate "lw16_sw16_operand"
+  (and (match_code "mem")
+       (match_test "m16_based_address_p (XEXP (op, 0), mode, uw4_operand)")))
+
+(define_predicate "lhu16_sh16_operand"
+  (and (match_code "mem")
+       (match_test "m16_based_address_p (XEXP (op, 0), mode, uh4_operand)")))
+
+(define_predicate "lbu16_operand"
+  (and (match_code "mem")
+       (match_test "m16_based_address_p (XEXP (op, 0), mode, db4_operand)")))
+
+(define_predicate "sb16_operand"
+  (and (match_code "mem")
+       (match_test "m16_based_address_p (XEXP (op, 0), mode, ub4_operand)")))
+
+(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 "sb4_operand"
+  (and (match_code "const_int")
+       (match_test "mips_signed_immediate_p (INTVAL (op), 4, 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 "uw6_operand"
+  (and (match_code "const_int")
+       (match_test "mips_unsigned_immediate_p (INTVAL (op), 6, 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)"))