gcc/ChangeLog: * config/i386/i386.md (ashr<mode>3_cvt_nf): New define_insn. (*<insn><mode>3_1_nf): Ditto.
gcc/testsuite/ChangeLog: * gcc.target/i386/apx-nf.c: Add NF test for rotate insns. --- gcc/config/i386/i386.md | 80 ++++++++++++++++++++++++++ gcc/testsuite/gcc.target/i386/apx-nf.c | 5 ++ 2 files changed, 85 insertions(+) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index adcb09fcdd0..ff44154b26b 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -16491,6 +16491,25 @@ (define_mode_attr cvt_mnemonic [(SI "{cltd|cdq}") (DI "{cqto|cqo}")]) +(define_insn "ashr<mode>3_cvt_nf" + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") + (ashiftrt:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") + (match_operand:QI 2 "const_int_operand")))] + "TARGET_APX_NF && + INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1 + && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) + && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands, TARGET_APX_NDD)" + "@ + %{nf%} sar{<imodesuffix>}\t{%2, %0|%0, %2} + %{nf%} sar{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + [(set_attr "isa" "*,apx_ndd") + (set_attr "type" "ishift") + (set_attr "prefix_0f" "*") + (set_attr "length_immediate" "*") + (set_attr "modrm" "1") + (set_attr "mode" "<MODE>")]) + (define_insn "ashr<mode>3_cvt" [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm,r") (ashiftrt:SWI48 @@ -17430,6 +17449,39 @@ [(set_attr "type" "rotatex") (set_attr "mode" "<MODE>")]) +(define_insn "*<insn><mode>3_1_nf" + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") + (any_rotate:SWI48 + (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") + (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))] + "TARGET_APX_NF && + ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)" +{ + bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; + if (operands[2] == const1_rtx + && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) + && !use_ndd) + return "%{nf%} <rotate>{<imodesuffix>}\t%0"; + else + return use_ndd ? "%{nf%} <rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "%{nf%} <rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; } + [(set_attr "isa" "*,apx_ndd") + (set_attr "type" "rotate") + (set (attr "preferred_for_size") + (cond [(eq_attr "alternative" "0") + (symbol_ref "true")] + (symbol_ref "false"))) + (set (attr "length_immediate") + (if_then_else + (and (eq_attr "type" "rotate") + (and (match_operand 2 "const1_operand") + (ior (match_test "TARGET_SHIFT1") + (match_test "optimize_function_for_size_p (cfun)")))) + (const_string "0") + (const_string "*"))) + (set_attr "mode" "<MODE>")]) + (define_insn "*<insn><mode>3_1" [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") (any_rotate:SWI48 @@ -17572,6 +17624,34 @@ [(set (match_dup 0) (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) +(define_insn "*<insn><mode>3_1_nf" + [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r") + (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm") + (match_operand:QI 2 "nonmemory_operand" "c<S>,c<S>")))] + "TARGET_APX_NF && + ix86_binary_operator_ok (<CODE>, <MODE>mode, operands, TARGET_APX_NDD)" +{ + bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; + if (operands[2] == const1_rtx + && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) + && !use_ndd) + return "%{nf%} <rotate>{<imodesuffix>}\t%0"; + else + return use_ndd + ? "%{nf%} <rotate>{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" + : "%{nf%} <rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; } + [(set_attr "isa" "*,apx_ndd") + (set_attr "type" "rotate") + (set (attr "length_immediate") + (if_then_else + (and (match_operand 2 "const1_operand") + (ior (match_test "TARGET_SHIFT1") + (match_test "optimize_function_for_size_p (cfun)"))) + (const_string "0") + (const_string "*"))) + (set_attr "mode" "<MODE>")]) + (define_insn "*<insn><mode>3_1" [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m,r") (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0,rm") diff --git a/gcc/testsuite/gcc.target/i386/apx-nf.c b/gcc/testsuite/gcc.target/i386/apx-nf.c index 608dbf8f5f7..6e59803be64 100644 --- a/gcc/testsuite/gcc.target/i386/apx-nf.c +++ b/gcc/testsuite/gcc.target/i386/apx-nf.c @@ -3,6 +3,7 @@ /* { dg-final { scan-assembler-times "\{nf\} add" 4 } } */ /* { dg-final { scan-assembler-times "\{nf\} and" 1 } } */ /* { dg-final { scan-assembler-times "\{nf\} or" 1 } } */ +/* { dg-final { scan-assembler-times "\{nf\} rol" 4 } } */ #include "apx-ndd.c" @@ -13,3 +14,7 @@ foo (struct B *b) { b->bit0 = b->bit0 | b->bit1; } +long int f1 (int x) { return ~(1ULL << (x & 0x3f)); } long int f2 (int +x) { return ~(1ULL << x); } long int f3 (unsigned char *x) { return +~(1ULL << (x[0] & 0x3f)); } long int f4 (unsigned char *x) { return +~(1ULL << x[0]); } -- 2.31.1