@@ -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
@@ -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]); }