Patchwork [MIPS,committed] Use microMIPS-style constraints for MIPS16

login
register
mail settings
Submitter Richard Sandiford
Date May 10, 2013, 10:54 a.m.
Message ID <874nebt88u.fsf@talisman.default>
Download mbox | patch
Permalink /patch/242960/
State New
Headers show

Comments

Richard Sandiford - May 10, 2013, 10:54 a.m.
This patch makes the MIPS16 length checks use the style of predicates
and constraints that were added for microMIPS.  Some constraints and
predicates are shared between the two ISA encodings, while others are
only useful for one or the other.

This is supposed to be a 1:1 change.  I haven't tried to catch more cases,
since that should be a separate patch.

For now I've kept using "extended_mips16" as the attribute of choice.
We could look at extending the "compression" attribute to MIPS16
(as Catherine's patch originally did), but that's likewise a separate
patch.

Tested on mips-sde-elf (with micromips multilibs locally patched out).
Applied.

Richard


gcc/
	* config/mips/mips-protos.h (m16_uimm3_b, m16_simm4_1, m16_nsimm4_1)
	(m16_simm5_1, m16_nsimm5_1, m16_uimm5_4, m16_nuimm5_4, m16_simm8_1)
	(m16_nsimm8_1, m16_uimm8_1, m16_nuimm8_1, m16_uimm8_m1_1, m16_uimm8_4)
	(m16_nuimm8_4, m16_simm8_8, m16_nsimm8_8): Delete.
	* config/mips/mips.c (m16_check_op, m16_uimm3_b, m16_simm4_1)
	(m16_nsimm4_1, m16_simm5_1, m16_nsimm5_1, m16_uimm5_4, m16_nuimm5_4)
	(m16_simm8_1, m16_nsimm8_1, m16_uimm8_1, m16_nuimm8_1, m16_uimm8_m1_1)
	(m16_uimm8_4, m16_nuimm8_4, m16_simm8_8, m16_nsimm8_8): Delete.
	* config/mips/constraints.md (Udb8, Usb5, Usb8, Usd8, Uub8, Uuw5)
	(Uuw8): New constraints.
	(Usb4): Move into alphabetical order.
	* config/mips/predicates.md (db8_operand, sb5_operand, sb8_operand)
	(sd8_operand, ub8_operand, uw8_operand): New predicates.
	* config/mips/mips.md (*xor<mode>3, *xor<mode>3_mips16): Name
	previously unnamed patterns.
	(*add<mode>3_mips16, *xor<mode>3_mips16, *<optab>si3_mips16)
	(*ashldi3_mips16, *ashrdi3_mips16, *lshrdi3_mips16)
	(*slt<u>_<GPR:mode><GPR2:mode>_mips16)
	(*sle<u>_<GPR:mode><GPR2:mode>_mips16): Use constraints instead
	of set_attr_alternative/if_then_else.  Use extended_mips16 instead
	of specific lengths.

Patch

Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h	2013-05-05 10:07:31.808505873 +0100
+++ gcc/config/mips/mips-protos.h	2013-05-05 10:08:54.009030051 +0100
@@ -211,23 +211,6 @@  extern rtx mips_strip_unspec_address (rt
 extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT);
 extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
 
-extern int m16_uimm3_b (rtx, enum machine_mode);
-extern int m16_simm4_1 (rtx, enum machine_mode);
-extern int m16_nsimm4_1 (rtx, enum machine_mode);
-extern int m16_simm5_1 (rtx, enum machine_mode);
-extern int m16_nsimm5_1 (rtx, enum machine_mode);
-extern int m16_uimm5_4 (rtx, enum machine_mode);
-extern int m16_nuimm5_4 (rtx, enum machine_mode);
-extern int m16_simm8_1 (rtx, enum machine_mode);
-extern int m16_nsimm8_1 (rtx, enum machine_mode);
-extern int m16_uimm8_1 (rtx, enum machine_mode);
-extern int m16_nuimm8_1 (rtx, enum machine_mode);
-extern int m16_uimm8_m1_1 (rtx, enum machine_mode);
-extern int m16_uimm8_4 (rtx, enum machine_mode);
-extern int m16_nuimm8_4 (rtx, enum machine_mode);
-extern int m16_simm8_8 (rtx, enum machine_mode);
-extern int m16_nsimm8_8 (rtx, enum machine_mode);
-
 extern rtx mips_subword (rtx, bool);
 extern bool mips_split_move_p (rtx, rtx, enum mips_split_type);
 extern void mips_split_move (rtx, rtx, enum mips_split_type);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2013-05-05 10:08:50.629997872 +0100
+++ gcc/config/mips/mips.c	2013-05-05 10:08:54.015030107 +0100
@@ -3357,113 +3357,6 @@  mips_rewrite_small_data (rtx pattern)
   return pattern;
 }
 
-/* We need a lot of little routines to check the range of MIPS16 immediate
-   operands.  */
-
-static int
-m16_check_op (rtx op, int low, int high, int mask)
-{
-  return (CONST_INT_P (op)
-	  && IN_RANGE (INTVAL (op), low, high)
-	  && (INTVAL (op) & mask) == 0);
-}
-
-int
-m16_uimm3_b (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, 0x1, 0x8, 0);
-}
-
-int
-m16_simm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x8, 0x7, 0);
-}
-
-int
-m16_nsimm4_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x7, 0x8, 0);
-}
-
-int
-m16_simm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x10, 0xf, 0);
-}
-
-int
-m16_nsimm5_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0xf, 0x10, 0);
-}
-
-int
-m16_uimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x10 << 2, 0xf << 2, 3);
-}
-
-int
-m16_nuimm5_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0xf << 2, 0x10 << 2, 3);
-}
-
-int
-m16_simm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x80, 0x7f, 0);
-}
-
-int
-m16_nsimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x7f, 0x80, 0);
-}
-
-int
-m16_uimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, 0x0, 0xff, 0);
-}
-
-int
-m16_nuimm8_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0xff, 0x0, 0);
-}
-
-int
-m16_uimm8_m1_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x1, 0xfe, 0);
-}
-
-int
-m16_uimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, 0x0, 0xff << 2, 3);
-}
-
-int
-m16_nuimm8_4 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0xff << 2, 0x0, 3);
-}
-
-int
-m16_simm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x80 << 3, 0x7f << 3, 7);
-}
-
-int
-m16_nsimm8_8 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
-  return m16_check_op (op, -0x7f << 3, 0x80 << 3, 7);
-}
-
 /* The cost of loading values from the constant pool.  It should be
    larger than the cost of any constant we want to synthesize inline.  */
 #define CONSTANT_POOL_COST COSTS_N_INSNS (TARGET_MIPS16 ? 4 : 8)
Index: gcc/config/mips/constraints.md
===================================================================
--- gcc/config/mips/constraints.md	2013-05-05 10:07:31.808505873 +0100
+++ gcc/config/mips/constraints.md	2013-05-08 18:23:29.864112705 +0100
@@ -178,6 +178,11 @@  (define_constraint "Udb7"
    A decremented unsigned constant of 7 bits."
   (match_operand 0 "db7_operand"))
 
+(define_constraint "Udb8"
+  "@internal
+   A decremented unsigned constant of 8 bits."
+  (match_operand 0 "db8_operand"))
+
 (define_constraint "Uead"
   "@internal
    A microMIPS encoded ADDIUR2 immediate operand."
@@ -198,15 +203,45 @@  (define_constraint "Uib3"
    An unsigned, incremented constant of 3 bits."
   (match_operand 0 "ib3_operand"))
 
+(define_constraint "Usb4"
+  "@internal
+   A signed constant of 4 bits."
+  (match_operand 0 "sb4_operand"))
+
+(define_constraint "Usb5"
+  "@internal
+   A signed constant of 5 bits."
+  (match_operand 0 "sb5_operand"))
+
+(define_constraint "Usb8"
+  "@internal
+   A signed constant of 8 bits."
+  (match_operand 0 "sb8_operand"))
+
+(define_constraint "Usd8"
+  "@internal
+   A signed constant of 8 bits, shifted left three places."
+  (match_operand 0 "sd8_operand"))
+
+(define_constraint "Uub8"
+  "@internal
+   An unsigned constant of 8 bits."
+  (match_operand 0 "ub8_operand"))
+
+(define_constraint "Uuw5"
+  "@internal
+   An unsigned constant of 5 bits, shifted left two places."
+  (match_operand 0 "uw5_operand"))
+
 (define_constraint "Uuw6"
   "@internal
    An unsigned constant of 6 bits, shifted left two places."
   (match_operand 0 "uw6_operand"))
 
-(define_constraint "Usb4"
+(define_constraint "Uuw8"
   "@internal
-   A signed constant of 4 bits."
-  (match_operand 0 "sb4_operand"))
+   An unsigned constant of 8 bits, shifted left two places."
+  (match_operand 0 "uw8_operand"))
 
 (define_memory_constraint "W"
   "@internal
Index: gcc/config/mips/predicates.md
===================================================================
--- gcc/config/mips/predicates.md	2013-05-05 10:07:31.808505873 +0100
+++ gcc/config/mips/predicates.md	2013-05-08 18:23:14.354951589 +0100
@@ -150,6 +150,10 @@  (define_predicate "db7_operand"
   (and (match_code "const_int")
        (match_test "mips_unsigned_immediate_p (INTVAL (op) + 1, 7, 0)")))
 
+(define_predicate "db8_operand"
+  (and (match_code "const_int")
+       (match_test "mips_unsigned_immediate_p (INTVAL (op) + 1, 8, 0)")))
+
 (define_predicate "ib3_operand"
   (and (match_code "const_int")
        (match_test "mips_unsigned_immediate_p (INTVAL (op) - 1, 3, 0)")))
@@ -158,10 +162,26 @@  (define_predicate "sb4_operand"
   (and (match_code "const_int")
        (match_test "mips_signed_immediate_p (INTVAL (op), 4, 0)")))
 
+(define_predicate "sb5_operand"
+  (and (match_code "const_int")
+       (match_test "mips_signed_immediate_p (INTVAL (op), 5, 0)")))
+
+(define_predicate "sb8_operand"
+  (and (match_code "const_int")
+       (match_test "mips_signed_immediate_p (INTVAL (op), 8, 0)")))
+
+(define_predicate "sd8_operand"
+  (and (match_code "const_int")
+       (match_test "mips_signed_immediate_p (INTVAL (op), 8, 3)")))
+
 (define_predicate "ub4_operand"
   (and (match_code "const_int")
        (match_test "mips_unsigned_immediate_p (INTVAL (op), 4, 0)")))
 
+(define_predicate "ub8_operand"
+  (and (match_code "const_int")
+       (match_test "mips_unsigned_immediate_p (INTVAL (op), 8, 0)")))
+
 (define_predicate "uh4_operand"
   (and (match_code "const_int")
        (match_test "mips_unsigned_immediate_p (INTVAL (op), 4, 1)")))
@@ -178,6 +198,10 @@  (define_predicate "uw6_operand"
   (and (match_code "const_int")
        (match_test "mips_unsigned_immediate_p (INTVAL (op), 6, 2)")))
 
+(define_predicate "uw8_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")
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2013-05-05 10:07:31.808505873 +0100
+++ gcc/config/mips/mips.md	2013-05-08 18:22:58.400784301 +0100
@@ -1166,32 +1166,23 @@  (define_insn "*add<mode>3"
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*add<mode>3_mips16"
-  [(set (match_operand:GPR 0 "register_operand" "=ks,d,d,d,d")
-	(plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,0,d,d")
-		  (match_operand:GPR 2 "arith_operand" "Q,Q,Q,O,d")))]
+  [(set (match_operand:GPR 0 "register_operand" "=ks,ks,d,d,d,d,d,d,d")
+	(plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,ks,ks,0,0,d,d,d")
+		  (match_operand:GPR 2 "arith_operand" "Usd8,Q,Uuw<si8_di5>,Q,Usb<si8_di5>,Q,Usb4,O,d")))]
   "TARGET_MIPS16"
   "@
     <d>addiu\t%0,%2
+    <d>addiu\t%0,%2
+    <d>addiu\t%0,%1,%2
     <d>addiu\t%0,%1,%2
     <d>addiu\t%0,%2
+    <d>addiu\t%0,%2
+    <d>addiu\t%0,%1,%2
     <d>addiu\t%0,%1,%2
     <d>addu\t%0,%1,%2"
   [(set_attr "alu_type" "add")
    (set_attr "mode" "<MODE>")
-   (set_attr_alternative "length"
-		[(if_then_else (match_operand 2 "m16_simm8_8")
-			       (const_int 4)
-			       (const_int 8))
-		 (if_then_else (match_operand 2 "m16_uimm<si8_di5>_4")
-			       (const_int 4)
-			       (const_int 8))
-		 (if_then_else (match_operand 2 "m16_simm<si8_di5>_1")
-			       (const_int 4)
-			       (const_int 8))
-		 (if_then_else (match_operand 2 "m16_simm4_1")
-			       (const_int 4)
-			       (const_int 8))
-		 (const_int 4)])])
+   (set_attr "extended_mips16" "no,yes,no,yes,no,yes,no,yes,no")])
 
 ;; On the mips16, we can sometimes split an add of a constant which is
 ;; a 4 byte instruction into two adds which are both 2 byte
@@ -3009,7 +3000,7 @@  (define_expand "xor<mode>3"
   ""
   "")
 
-(define_insn ""
+(define_insn "*xor<mode>3"
   [(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")))]
@@ -3022,23 +3013,19 @@  (define_insn ""
    (set_attr "compression" "micromips,*,*")
    (set_attr "mode" "<MODE>")])
 
-(define_insn ""
-  [(set (match_operand:GPR 0 "register_operand" "=d,t,t")
-	(xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d")
-		 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))]
+(define_insn "*xor<mode>3_mips16"
+  [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
+	(xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
+		 (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
   "TARGET_MIPS16"
   "@
    xor\t%0,%2
    cmpi\t%1,%2
+   cmpi\t%1,%2
    cmp\t%1,%2"
   [(set_attr "alu_type" "xor")
    (set_attr "mode" "<MODE>")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand:VOID 2 "m16_uimm8_1")
-			       (const_int 4)
-			       (const_int 8))
-		 (const_int 4)])])
+   (set_attr "extended_mips16" "no,no,yes,no")])
 
 (define_insn "*nor<mode>3"
   [(set (match_operand:GPR 0 "register_operand" "=d")
@@ -5294,9 +5281,9 @@  (define_insn "*<optab>si3_extend"
    (set_attr "mode" "SI")])
 
 (define_insn "*<optab>si3_mips16"
-  [(set (match_operand:SI 0 "register_operand" "=d,d")
-	(any_shift:SI (match_operand:SI 1 "register_operand" "0,d")
-		      (match_operand:SI 2 "arith_operand" "d,I")))]
+  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+	(any_shift:SI (match_operand:SI 1 "register_operand" "0,d,d")
+		      (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
   "TARGET_MIPS16"
 {
   if (which_alternative == 0)
@@ -5307,18 +5294,14 @@  (define_insn "*<optab>si3_mips16"
 }
   [(set_attr "type" "shift")
    (set_attr "mode" "SI")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand 2 "m16_uimm3_b")
-			       (const_int 4)
-			       (const_int 8))])])
+   (set_attr "extended_mips16" "no,no,yes")])
 
 ;; We need separate DImode MIPS16 patterns because of the irregularity
 ;; of right shifts.
 (define_insn "*ashldi3_mips16"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
-	(ashift:DI (match_operand:DI 1 "register_operand" "0,d")
-		   (match_operand:SI 2 "arith_operand" "d,I")))]
+  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
+	(ashift:DI (match_operand:DI 1 "register_operand" "0,d,d")
+		   (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
   "TARGET_64BIT && TARGET_MIPS16"
 {
   if (which_alternative == 0)
@@ -5329,16 +5312,12 @@  (define_insn "*ashldi3_mips16"
 }
   [(set_attr "type" "shift")
    (set_attr "mode" "DI")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand 2 "m16_uimm3_b")
-			       (const_int 4)
-			       (const_int 8))])])
+   (set_attr "extended_mips16" "no,no,yes")])
 
 (define_insn "*ashrdi3_mips16"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
-	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
-		     (match_operand:SI 2 "arith_operand" "d,I")))]
+  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
+	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
+		     (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
   "TARGET_64BIT && TARGET_MIPS16"
 {
   if (CONST_INT_P (operands[2]))
@@ -5348,16 +5327,12 @@  (define_insn "*ashrdi3_mips16"
 }
   [(set_attr "type" "shift")
    (set_attr "mode" "DI")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand 2 "m16_uimm3_b")
-			       (const_int 4)
-			       (const_int 8))])])
+   (set_attr "extended_mips16" "no,no,yes")])
 
 (define_insn "*lshrdi3_mips16"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
-	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
-		     (match_operand:SI 2 "arith_operand" "d,I")))]
+  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
+	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
+		     (match_operand:SI 2 "arith_operand" "d,Uib3,I")))]
   "TARGET_64BIT && TARGET_MIPS16"
 {
   if (CONST_INT_P (operands[2]))
@@ -5367,11 +5342,7 @@  (define_insn "*lshrdi3_mips16"
 }
   [(set_attr "type" "shift")
    (set_attr "mode" "DI")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand 2 "m16_uimm3_b")
-			       (const_int 4)
-			       (const_int 8))])])
+   (set_attr "extended_mips16" "no,no,yes")])
 
 ;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts.
 
@@ -5756,18 +5727,14 @@  (define_insn "*slt<u>_<GPR:mode><GPR2:mo
    (set_attr "mode" "<GPR:MODE>")])
 
 (define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16"
-  [(set (match_operand:GPR2 0 "register_operand" "=t,t")
-	(any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
-		     (match_operand:GPR 2 "arith_operand" "d,I")))]
+  [(set (match_operand:GPR2 0 "register_operand" "=t,t,t")
+	(any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d,d")
+		     (match_operand:GPR 2 "arith_operand" "d,Uub8,I")))]
   "TARGET_MIPS16"
   "slt<u>\t%1,%2"
   [(set_attr "type" "slt")
    (set_attr "mode" "<GPR:MODE>")
-   (set_attr_alternative "length"
-		[(const_int 4)
-		 (if_then_else (match_operand 2 "m16_uimm8_1")
-			       (const_int 4)
-			       (const_int 8))])])
+   (set_attr "extended_mips16" "no,no,yes")])
 
 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>"
   [(set (match_operand:GPR2 0 "register_operand" "=d")
@@ -5782,9 +5749,9 @@  (define_insn "*sle<u>_<GPR:mode><GPR2:mo
    (set_attr "mode" "<GPR:MODE>")])
 
 (define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16"
-  [(set (match_operand:GPR2 0 "register_operand" "=t")
-	(any_le:GPR2 (match_operand:GPR 1 "register_operand" "d")
-		     (match_operand:GPR 2 "sle_operand" "")))]
+  [(set (match_operand:GPR2 0 "register_operand" "=t,t")
+	(any_le:GPR2 (match_operand:GPR 1 "register_operand" "d,d")
+		     (match_operand:GPR 2 "sle_operand" "Udb8,i")))]
   "TARGET_MIPS16"
 {
   operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
@@ -5792,9 +5759,7 @@  (define_insn "*sle<u>_<GPR:mode><GPR2:mo
 }
   [(set_attr "type" "slt")
    (set_attr "mode" "<GPR:MODE>")
-   (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1")
-				      (const_int 4)
-				      (const_int 8)))])
+   (set_attr "extended_mips16" "no,yes")])
 
 ;;
 ;;  ....................