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. 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")]) ;; ;; ....................