From 8e6a558d4123185962a54de53b104310e248880d Mon Sep 17 00:00:00 2001 From: Lingling Kong Date: Mon, 3 Jun 2024 11:05:41 +0800 Subject: [PATCH] [APX NF] Support APX NF for left shift insns gcc/ChangeLog: * config/i386/i386.md (*ashl3_1): New define_insn. (*ashlhi3_1): Ditto. (*ashlqi3_1): Ditto. * config/i386/sse.md: New define_split. --- gcc/config/i386/i386.md | 96 ++++++++++++++++++++++++++++++----------- gcc/config/i386/sse.md | 13 ++++++ 2 files changed, 83 insertions(+), 26 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 5653f5ce123..8063cb576f5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15013,17 +15013,22 @@ [(set_attr "type" "ishiftx") (set_attr "mode" "")]) -(define_insn "*ashl3_1" +(define_insn "*ashl3_1" [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k,r") (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k,rm") - (match_operand:QI 2 "nonmemory_operand" "c,M,r,,c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ASHIFT, mode, operands, TARGET_APX_NDD)" + (match_operand:QI 2 "nonmemory_operand" "c,M,r,,c")))] + "ix86_binary_operator_ok (ASHIFT, mode, operands, TARGET_APX_NDD) + && " { bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; switch (get_attr_type (insn)) { case TYPE_LEA: + if (TARGET_APX_NDD && ) + return "%{nf%} sal{}\t{%2, %1, %0|%0, %1, %2}"; + else + return "#"; + case TYPE_ISHIFTX: case TYPE_MSKLOG: return "#"; @@ -15031,7 +15036,7 @@ case TYPE_ALU: gcc_assert (operands[2] == const1_rtx); gcc_assert (rtx_equal_p (operands[0], operands[1])); - return "add{}\t%0, %0"; + return "add{}\t%0, %0"; default: if (operands[2] == const1_rtx @@ -15039,11 +15044,11 @@ /* For NDD form instructions related to TARGET_SHIFT1, the $1 immediate do not need to be omitted as assembler will map it to use shorter encoding. */ - && !use_ndd) + && !use_ndd && !) return "sal{}\t%0"; else - return use_ndd ? "sal{}\t{%2, %1, %0|%0, %1, %2}" - : "sal{}\t{%2, %0|%0, %2}"; + return use_ndd ? "sal{}\t{%2, %1, %0|%0, %1, %2}" + : "sal{}\t{%2, %0|%0, %2}"; } } [(set_attr "isa" "*,*,bmi2,avx512bw,apx_ndd") @@ -15074,6 +15079,17 @@ (set_attr "mode" "")]) ;; Convert shift to the shiftx pattern to avoid flags dependency. +;; For NF/NDD doesn't support shift count as r, it just support c, +;; and it has no flag. +(define_split + [(set (match_operand:SWI48 0 "register_operand") + (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") + (match_operand:QI 2 "register_operand")))] + "TARGET_BMI2 && reload_completed" + [(set (match_dup 0) + (ashift:SWI48 (match_dup 1) (match_dup 2)))] + "operands[2] = gen_lowpart (mode, operands[2]);") + (define_split [(set (match_operand:SWI48 0 "register_operand") (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") @@ -15160,32 +15176,37 @@ (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] "operands[2] = gen_lowpart (SImode, operands[2]);") -(define_insn "*ashlhi3_1" +(define_insn "*ashlhi3_1" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k,r") (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k,rm") - (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD)" + (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww,cI")))] + "ix86_binary_operator_ok (ASHIFT, HImode, operands, TARGET_APX_NDD) + && " { bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; switch (get_attr_type (insn)) { case TYPE_LEA: + if (TARGET_APX_NDD && ) + return "%{nf%} sal{w}\t{%2, %1, %0|%0, %1, %2}"; + else + return "#"; + case TYPE_MSKLOG: return "#"; case TYPE_ALU: gcc_assert (operands[2] == const1_rtx); - return "add{w}\t%0, %0"; + return "add{w}\t%0, %0"; default: if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && !use_ndd) + && !use_ndd && !) return "sal{w}\t%0"; else - return use_ndd ? "sal{w}\t{%2, %1, %0|%0, %1, %2}" - : "sal{w}\t{%2, %0|%0, %2}"; + return use_ndd ? "sal{w}\t{%2, %1, %0|%0, %1, %2}" + : "sal{w}\t{%2, %0|%0, %2}"; } } [(set_attr "isa" "*,*,avx512f,apx_ndd") @@ -15213,31 +15234,36 @@ (const_string "*"))) (set_attr "mode" "HI,SI,HI,HI")]) -(define_insn "*ashlqi3_1" +(define_insn "*ashlqi3_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k,r") (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k,rm") - (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD)" + (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb,cI")))] + "ix86_binary_operator_ok (ASHIFT, QImode, operands, TARGET_APX_NDD) + && " { bool use_ndd = get_attr_isa (insn) == ISA_APX_NDD; switch (get_attr_type (insn)) { case TYPE_LEA: + if (TARGET_APX_NDD && ) + return "%{nf%} sal{b}\t{%2, %1, %0|%0, %1, %2}"; + else + return "#"; + case TYPE_MSKLOG: return "#"; case TYPE_ALU: gcc_assert (operands[2] == const1_rtx); if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1]))) - return "add{l}\t%k0, %k0"; + return "add{l}\t%k0, %k0"; else - return "add{b}\t%0, %0"; + return "add{b}\t%0, %0"; default: if (operands[2] == const1_rtx && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && !use_ndd) + && !use_ndd && !) { if (get_attr_mode (insn) == MODE_SI) return "sal{l}\t%k0"; @@ -15247,10 +15273,10 @@ else { if (get_attr_mode (insn) == MODE_SI) - return "sal{l}\t{%2, %k0|%k0, %2}"; + return "sal{l}\t{%2, %k0|%k0, %2}"; else - return use_ndd ? "sal{b}\t{%2, %1, %0|%0, %1, %2}" - : "sal{b}\t{%2, %0|%0, %2}"; + return use_ndd ? "sal{b}\t{%2, %1, %0|%0, %1, %2}" + : "sal{b}\t{%2, %0|%0, %2}"; } } } @@ -15353,6 +15379,24 @@ operands[2] = GEN_INT (1 << INTVAL (operands[2])); }) +(define_split + [(set (match_operand:SWI 0 "general_reg_operand") + (ashift:SWI (match_operand:SWI 1 "index_reg_operand") + (match_operand 2 "const_0_to_3_operand")))] + "reload_completed + && REGNO (operands[0]) != REGNO (operands[1]) + && !TARGET_APX_NDD" + [(set (match_dup 0) + (mult: (match_dup 1) (match_dup 2)))] +{ + if (mode != mode) + { + operands[0] = gen_lowpart (mode, operands[0]); + operands[1] = gen_lowpart (mode, operands[1]); + } + operands[2] = GEN_INT (1 << INTVAL (operands[2])); +}) + ;; Convert ashift to the lea pattern to avoid flags dependency. (define_split [(set (match_operand:DI 0 "general_reg_operand") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index ca560b639b8..4ad3917f5ce 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -2150,6 +2150,19 @@ (set_attr "prefix" "vex") (set_attr "mode" "")]) +(define_split + [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand") + (any_lshift:SWI1248_AVX512BW + (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand") + (match_operand 2 "const_int_operand")))] + "TARGET_AVX512F && reload_completed" + [(parallel + [(set (match_dup 0) + (any_lshift:SWI1248_AVX512BW + (match_dup 1) + (match_dup 2))) + (unspec [(const_int 0)] UNSPEC_MASKOP)])]) + (define_split [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand") (any_lshift:SWI1248_AVX512BW -- 2.47.2