diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32b916cb199..bf1f125340c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2004-10-11 Richard Sandiford + + * config/frv/frv.md (*adddi3_internal): Change name to... + (adddi3): ...replacing the exisiting define_expand. Combine + alternatives. Fix the range of the constant constraints ('J' instead + of 'NOP'). Remove bogus operands[2] check. Use simplify_gen_subreg + to extract the lower and upper halves of the DImode operands. + Always use addi3_lower and adddi3_upper, not the subdi3 forms. + (adddi3_lower): Fix the range of the constant constraints and + remove the bogus operands[2] check. + (adddi3_upper): Use gpr_or_int10_operand as the predicate for + operand 2. Use addxi to handle constant operands. + (subdi3_lower, subdi3_upper): Don't handle constant operands. + 2004-10-11 Nathan Sidwell * gengtype-lex.l: Add commented } & ) characters to unconfuse diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md index 0cf88871455..ee17edabed8 100644 --- a/gcc/config/frv/frv.md +++ b/gcc/config/frv/frv.md @@ -2940,57 +2940,30 @@ ;; :::::::::::::::::::: ;; Addition -(define_expand "adddi3" - [(parallel [(set (match_operand:DI 0 "integer_register_operand" "") - (plus:DI (match_operand:DI 1 "integer_register_operand" "") - (match_operand:DI 2 "gpr_or_int10_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] +(define_insn_and_split "adddi3" + [(set (match_operand:DI 0 "integer_register_operand" "=&e,e") + (plus:DI (match_operand:DI 1 "integer_register_operand" "%e,0") + (match_operand:DI 2 "gpr_or_int10_operand" "eJ,eJ"))) + (clobber (match_scratch:CC 3 "=t,t"))] "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) == -2048 - && !no_new_pseudos) - operands[2] = force_reg (DImode, operands[2]); -}") - -(define_insn_and_split "*adddi3_internal" - [(set (match_operand:DI 0 "integer_register_operand" "=&e,e,e,&e,e,&e,e") - (plus:DI (match_operand:DI 1 "integer_register_operand" "%e,0,e,e,0,e,0") - (match_operand:DI 2 "gpr_or_int10_operand" "e,e,0,N,N,OP,OP"))) - (clobber (match_scratch:CC 3 "=t,t,t,t,t,t,t"))] - "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -2048" "#" "reload_completed" [(match_dup 4) (match_dup 5)] " { - rtx op0_high = gen_highpart (SImode, operands[0]); - rtx op1_high = gen_highpart (SImode, operands[1]); - rtx op0_low = gen_lowpart (SImode, operands[0]); - rtx op1_low = gen_lowpart (SImode, operands[1]); - rtx op2 = operands[2]; - rtx op3 = operands[3]; + rtx parts[3][2]; + int op, part; - if (GET_CODE (op2) != CONST_INT) - { - rtx op2_high = gen_highpart (SImode, operands[2]); - rtx op2_low = gen_lowpart (SImode, operands[2]); - operands[4] = gen_adddi3_lower (op0_low, op1_low, op2_low, op3); - operands[5] = gen_adddi3_upper (op0_high, op1_high, op2_high, op3); - } - else if (INTVAL (op2) >= 0) - { - operands[4] = gen_adddi3_lower (op0_low, op1_low, op2, op3); - operands[5] = gen_adddi3_upper (op0_high, op1_high, const0_rtx, op3); - } - else - { - operands[4] = gen_subdi3_lower (op0_low, op1_low, - GEN_INT (- INTVAL (op2)), op3); - operands[5] = gen_subdi3_upper (op0_high, op1_high, const0_rtx, op3); - } + for (op = 0; op < 3; op++) + for (part = 0; part < 2; part++) + parts[op][part] = simplify_gen_subreg (SImode, operands[op], + DImode, part * UNITS_PER_WORD); + + operands[4] = gen_adddi3_lower (parts[0][1], parts[1][1], parts[2][1], + operands[3]); + operands[5] = gen_adddi3_upper (parts[0][0], parts[1][0], parts[2][0], + copy_rtx (operands[3])); }" [(set_attr "length" "8") (set_attr "type" "multi")]) @@ -3027,50 +3000,46 @@ (define_insn "adddi3_lower" [(set (match_operand:SI 0 "integer_register_operand" "=d") (plus:SI (match_operand:SI 1 "integer_register_operand" "d") - (match_operand:SI 2 "gpr_or_int10_operand" "dOP"))) + (match_operand:SI 2 "gpr_or_int10_operand" "dJ"))) (set (match_operand:CC 3 "icc_operand" "=t") (compare:CC (plus:SI (match_dup 1) (match_dup 2)) (const_int 0)))] - "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 0" + "" "add%I2cc %1,%2,%0,%3" [(set_attr "length" "4") (set_attr "type" "int")]) (define_insn "adddi3_upper" - [(set (match_operand:SI 0 "integer_register_operand" "=d,d") - (plus:SI (match_operand:SI 1 "integer_register_operand" "d,d") - (plus:SI (match_operand:SI 2 "reg_or_0_operand" "d,O") - (match_operand:CC 3 "icc_operand" "t,t"))))] + [(set (match_operand:SI 0 "integer_register_operand" "=d") + (plus:SI (match_operand:SI 1 "integer_register_operand" "d") + (plus:SI (match_operand:SI 2 "gpr_or_int10_operand" "dJ") + (match_operand:CC 3 "icc_operand" "t"))))] "" - "@ - addx %1,%2,%0,%3 - addx %1,%.,%0,%3" + "addx%I2 %1,%2,%0,%3" [(set_attr "length" "4") (set_attr "type" "int")]) (define_insn "subdi3_lower" [(set (match_operand:SI 0 "integer_register_operand" "=d") (minus:SI (match_operand:SI 1 "integer_register_operand" "d") - (match_operand:SI 2 "gpr_or_int10_operand" "dOP"))) + (match_operand:SI 2 "integer_register_operand" "d"))) (set (match_operand:CC 3 "icc_operand" "=t") (compare:CC (plus:SI (match_dup 1) (match_dup 2)) (const_int 0)))] - "GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 0" - "sub%I2cc %1,%2,%0,%3" + "" + "subcc %1,%2,%0,%3" [(set_attr "length" "4") (set_attr "type" "int")]) (define_insn "subdi3_upper" - [(set (match_operand:SI 0 "integer_register_operand" "=d,d") - (minus:SI (match_operand:SI 1 "integer_register_operand" "d,d") - (minus:SI (match_operand:SI 2 "reg_or_0_operand" "d,O") - (match_operand:CC 3 "icc_operand" "t,t"))))] + [(set (match_operand:SI 0 "integer_register_operand" "=d") + (minus:SI (match_operand:SI 1 "integer_register_operand" "d") + (minus:SI (match_operand:SI 2 "integer_register_operand" "d") + (match_operand:CC 3 "icc_operand" "t"))))] "" - "@ - subx %1,%2,%0,%3 - subx %1,%.,%0,%3" + "subx %1,%2,%0,%3" [(set_attr "length" "4") (set_attr "type" "int")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 632dc18d594..5009857d221 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-10-11 Richard Sandiford + + * gcc.c-torture/execute/20041011-1.c: New test. + 2004-10-10 Andrew Pinski PR c++/17554 diff --git a/gcc/testsuite/gcc.c-torture/execute/20041011-1.c b/gcc/testsuite/gcc.c-torture/execute/20041011-1.c new file mode 100644 index 00000000000..4524de9435f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20041011-1.c @@ -0,0 +1,60 @@ +typedef unsigned long long ull; +volatile int gvol[32]; +ull gull; + +#define MULTI(X) \ + X( 1), X( 2), X( 3), X( 4), X( 5), X( 6), X( 7), X( 8), X( 9), X(10), \ + X(11), X(12), X(13), X(14), X(15), X(16), X(17), X(18), X(19), X(20), \ + X(21), X(22), X(23), X(24), X(25), X(26), X(27), X(28), X(29), X(30) + +#define DECLARE(INDEX) x##INDEX +#define COPYIN(INDEX) x##INDEX = gvol[INDEX] +#define COPYOUT(INDEX) gvol[INDEX] = x##INDEX + +#define BUILD_TEST(NAME, N) \ + ull __attribute__((noinline)) \ + NAME (int n, ull x) \ + { \ + while (n--) \ + { \ + int MULTI (DECLARE); \ + MULTI (COPYIN); \ + MULTI (COPYOUT); \ + x += N; \ + } \ + return x; \ + } + +#define RUN_TEST(NAME, N) \ + if (NAME (3, ~0ULL) != N * 3 - 1) \ + abort (); \ + if (NAME (3, 0xffffffffULL) \ + != N * 3 + 0xffffffffULL) \ + abort (); + +#define DO_TESTS(DO_TEST) \ + DO_TEST (t1, -2048) \ + DO_TEST (t2, -513) \ + DO_TEST (t3, -512) \ + DO_TEST (t4, -511) \ + DO_TEST (t5, -1) \ + DO_TEST (t6, 1) \ + DO_TEST (t7, 511) \ + DO_TEST (t8, 512) \ + DO_TEST (t9, 513) \ + DO_TEST (t10, gull) \ + DO_TEST (t11, -gull) + +DO_TESTS (BUILD_TEST) + +ull neg (ull x) { return -x; } + +int +main () +{ + gull = 100; + DO_TESTS (RUN_TEST) + if (neg (gull) != -100ULL) + abort (); + exit (0); +}