--- gcc/config/rx/constraints.md 2011-10-05 20:37:21.000000000 +0530 +++ gcc/config/rx/constraints.md 2012-11-06 17:09:02.000000000 +0530 @@ -106,3 +106,42 @@ ) ) ) + +(define_constraint "Uint03" + "An unsigned 3-bit constant, as used in bclr, bset, etc." + (and (match_code "const_int") + (match_test "ival >= 0 && ival <= 7"))) + +(define_constraint "Intu1" + "Integer constant 1." + (and (match_code "const_int") + (match_test "ival == 1"))) + +(define_constraint "Intu0" + "Integer constant 0." + (and (match_code "const_int") + (match_test "ival == 0"))) + +(define_constraint "Intsz" + "Integer constant with a single zero bit in the lower 8-bit." + (and (match_code "const_int") + (ior (match_test "~ival == 1") + (match_test "~ival == 2") + (match_test "~ival == 4") + (match_test "~ival == 8") + (match_test "~ival == 16") + (match_test "~ival == 32") + (match_test "~ival == 64") + (match_test "~ival == 128")))) + +(define_constraint "Intso" + "Integer constant with a single bit set in its lower 8-bit." + (and (match_code "const_int") + (ior (match_test "ival == 1") + (match_test "ival == 2") + (match_test "ival == 4") + (match_test "ival == 8") + (match_test "ival == 16") + (match_test "ival == 32") + (match_test "ival == 64") + (match_test "ival == 128")))) --- gcc/config/rx/predicates.md 2011-09-28 20:07:30.000000000 +0530 +++ gcc/config/rx/predicates.md 2012-11-06 17:09:23.000000000 +0530 @@ -47,6 +47,11 @@ (match_test "IN_RANGE (INTVAL (op), 0, 31)")) ) +(define_predicate "rx_constbit_operand" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 7)")) +) + (define_predicate "rx_restricted_mem_operand" (and (match_code "mem") (match_test "rx_is_restricted_memory_address (XEXP (op, 0), mode)")) --- gcc/config/rx/rx.c 2012-10-03 21:42:22.000000000 +0530 +++ gcc/config/rx/rx.c 2012-11-06 19:08:32.000000000 +0530 @@ -499,6 +499,8 @@ rx_assemble_integer (rtx x, unsigned int %A Print an operand without a leading # character. %B Print an integer comparison name. %C Print a control register name. + %D Print the position of a single bit set. + %E Print the position of a single bit cleared. %F Print a condition code flag name. %G Register used for small-data-area addressing %H Print high part of a DImode register, integer or address. @@ -646,6 +648,22 @@ rx_print_operand (FILE * file, rtx op, i } break; + case 'D': + { + int num = exact_log2 (INTVAL (op)); + gcc_assert (num >= 0); + fprintf (file, "#%d", num); + } + break; + + case 'E': + { + int num = exact_log2 (~INTVAL (op)); + gcc_assert (num >= 0); + fprintf (file, "#%d", num); + } + break; + case 'F': gcc_assert (CONST_INT_P (op)); switch (INTVAL (op)) --- gcc/config/rx/rx.md 2012-06-27 18:33:47.000000000 +0530 +++ gcc/config/rx/rx.md 2012-11-06 19:10:17.000000000 +0530 @@ -1956,6 +1956,35 @@ ;; bit offset, so that we can adjust the address by ofs/8 and replace ;; the offset in the insn by ofs%8. +(define_insn "iorbset_mem" + [(set (match_operand:QI 0 "rx_restricted_mem_operand" "=Q") + (ior:QI (match_operand:QI 1 "rx_restricted_mem_operand" "%0") + (match_operand 2 "const_int_operand" "Intso")))] + "satisfies_constraint_Intso (operands[2])" + "bset\\t%D2,%0.B" + [(set_attr "length" "3")] +) + +(define_insn "iorbset_reg" + [(set (match_operand:SI 0 "register_operand" "=r") + (ior:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand 2 "const_int_operand" "Intso")))] + "satisfies_constraint_Intso (operands[2])" + "bset\\t%D2,%0" + [(set_attr "length" "3")] +) + +(define_insn "bset" + [(set (zero_extract:SI + (match_operand:QI 0 "rx_restricted_mem_operand" "+Q") + (const_int 1) + (match_operand 1 "rx_constbit_operand" "Uint03")) + (const_int 1))] + "" + "bset\\t%1,%0.B" + [(set_attr "length" "3")] +) + (define_insn "*bitset" [(set (match_operand:SI 0 "register_operand" "=r") (ior:SI (ashift:SI (const_int 1) @@ -1966,7 +1995,7 @@ [(set_attr "length" "3")] ) -(define_insn "*bitset_in_memory" +(define_insn "bitset_in_memory" [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q") (ior:QI (ashift:QI (const_int 1) (match_operand:QI 1 "nonmemory_operand" "ri")) @@ -1977,6 +2006,24 @@ (set_attr "timings" "33")] ) +(define_insn "xorbnot_mem" + [(set (match_operand:QI 0 "rx_restricted_mem_operand" "=Q") + (xor:QI (match_operand:QI 1 "rx_restricted_mem_operand" "%0") + (match_operand 2 "const_int_operand" "Intso")))] + "satisfies_constraint_Intso (operands[2])" + "bnot\\t%D2,%0.B" + [(set_attr "length" "3")] +) + +(define_insn "xorbnot_reg" + [(set (match_operand:SI 0 "register_operand" "=r") + (xor:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand 2 "const_int_operand" "Intso")))] + "satisfies_constraint_Intso (operands[2])" + "bnot\\t%D2,%0" + [(set_attr "length" "3")] +) + (define_insn "*bitinvert" [(set (match_operand:SI 0 "register_operand" "=r") (xor:SI (ashift:SI (const_int 1) @@ -1998,6 +2045,35 @@ (set_attr "timings" "33")] ) +(define_insn "andbclr_mem" + [(set (match_operand:QI 0 "rx_restricted_mem_operand" "=Q") + (and:QI (match_operand:QI 1 "rx_restricted_mem_operand" "%0") + (match_operand 2 "const_int_operand" "Intsz")))] + "satisfies_constraint_Intsz (operands[2])" + "bclr\\t%E2,%0.B" + [(set_attr "length" "3")] +) + +(define_insn "andbclr_reg" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (match_operand:SI 1 "register_operand" "%0") + (match_operand 2 "const_int_operand" "Intsz")))] + "satisfies_constraint_Intsz (operands[2])" + "bclr\\t%E2,%0" + [(set_attr "length" "3")] +) + +(define_insn "bclr" + [(set (zero_extract:SI + (match_operand:QI 0 "rx_restricted_mem_operand" "+Q") + (const_int 1) + (match_operand 1 "rx_constbit_operand" "Uint03")) + (const_int 0))] + "" + "bclr\\t%1,%0.B" + [(set_attr "length" "3")] +) + (define_insn "*bitclr" [(set (match_operand:SI 0 "register_operand" "=r") (and:SI (not:SI @@ -2010,7 +2086,7 @@ [(set_attr "length" "3")] ) -(define_insn "*bitclr_in_memory" +(define_insn "bitclr_in_memory" [(set (match_operand:QI 0 "rx_restricted_mem_operand" "+Q") (and:QI (not:QI (ashift:QI @@ -2023,6 +2099,22 @@ (set_attr "timings" "33")] ) +(define_insn "*insv_mem_imm" + [(set (zero_extract:SI + (match_operand 0 "rx_restricted_mem_operand" "+Q") + (const_int 1) + (match_operand 1 "nonmemory_operand" "ri")) + (match_dup 0))] + "" +{ + if (INTVAL (operands[2]) & 1) + return "bset\t%1, %0.B"; + else + return "bclr\t%1, %0.B"; +} + [(set_attr "length" "3")] +) + (define_insn "*insv_imm" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") @@ -2124,16 +2216,37 @@ (define_expand "insv" [(set (zero_extract:SI - (match_operand:SI 0 "register_operand") ;; Destination - (match_operand:SI 1 "const_int_operand") ;; # of bits to set - (match_operand:SI 2 "nonmemory_operand")) ;; Starting bit - (match_operand:SI 3 "nonmemory_operand"))] ;; Bits to insert + (match_operand 0 "nonimmediate_operand") ;; Destination + (match_operand 1 "immediate_operand") ;; # of bits to set + (match_operand 2 "const_int_operand")) ;; Starting bit + (match_operand 3 "nonmemory_operand"))] ;; Bits to insert "" { /* We only handle single-bit inserts. */ if (!CONST_INT_P (operands[1]) || INTVAL (operands[1]) != 1) FAIL; + if (GET_CODE (operands [0]) == MEM + && (!CONST_INT_P (operands[2]) + || !CONST_INT_P (operands[3]) + || (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 7))) + FAIL; + + if (GET_CODE (operands [0]) == MEM + && satisfies_constraint_Intu1 (operands[1]) + && satisfies_constraint_Uint03 (operands[2])) + { + if (satisfies_constraint_Intu0 (operands[3])) + { + emit_insn (gen_bitclr_in_memory (operands[0], operands[1])); + DONE; + } + else if (satisfies_constraint_Intu1 (operands[3])) + { + emit_insn (gen_bitset_in_memory (operands[0], operands[2])); + DONE; + } + } /* Either the bit to insert or the position must be constant. */ if (CONST_INT_P (operands[3])) operands[3] = GEN_INT (INTVAL (operands[3]) & 1);