diff options
Diffstat (limited to 'gcc/config/i386')
-rw-r--r-- | gcc/config/i386/cpuid.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386-builtin-types.def | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386-builtin.def | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386-c.cc | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386-expand.cc | 77 | ||||
-rw-r--r-- | gcc/config/i386/i386-isa.def | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386-options.cc | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 23 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 4 | ||||
-rw-r--r-- | gcc/config/i386/predicates.md | 15 | ||||
-rw-r--r-- | gcc/config/i386/prfchiintrin.h | 49 | ||||
-rw-r--r-- | gcc/config/i386/x86gprintrin.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/xmmintrin.h | 7 |
13 files changed, 190 insertions, 3 deletions
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 229c15c5950..92583261883 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -54,6 +54,7 @@ #define bit_AVXVNNIINT8 (1 << 4) #define bit_AVXNECONVERT (1 << 5) #define bit_CMPXCHG8B (1 << 8) +#define bit_PREFETCHI (1 << 14) #define bit_CMOV (1 << 15) #define bit_MMX (1 << 23) #define bit_FXSAVE (1 << 24) diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index 2af66145d4b..d10de32643f 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -1411,3 +1411,7 @@ DEF_FUNCTION_TYPE (V8SF, PCV16BF) # CMPccXADD builtins DEF_FUNCTION_TYPE (INT, PINT, INT, INT, INT) DEF_FUNCTION_TYPE (LONGLONG, PLONGLONG, LONGLONG, LONGLONG, INT) + +# PREFETCHI builtins +DEF_FUNCTION_TYPE (VOID, PCVOID, INT) +DEF_FUNCTION_TYPE (VOID, PCVOID, INT, INT, INT) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index c272c392d03..837007ada8e 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -487,6 +487,10 @@ BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesdecwide2 BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesencwide128kl_u8", IX86_BUILTIN_AESENCWIDE128KLU8, UNKNOWN, (int) UINT8_FTYPE_PV2DI_PCV2DI_PCVOID) BDESC (0, OPTION_MASK_ISA2_WIDEKL, CODE_FOR_nothing, "__builtin_ia32_aesencwide256kl_u8", IX86_BUILTIN_AESENCWIDE256KLU8, UNKNOWN, (int) UINT8_FTYPE_PV2DI_PCV2DI_PCVOID) +/* PREFETCHI */ +BDESC (0, 0, CODE_FOR_prefetchi, "__builtin_ia32_prefetchi", IX86_BUILTIN_PREFETCHI, UNKNOWN, (int) VOID_FTYPE_PCVOID_INT) +BDESC (0, 0, CODE_FOR_nothing, "__builtin_ia32_prefetch", IX86_BUILTIN_PREFETCH, UNKNOWN, (int) VOID_FTYPE_PCVOID_INT_INT_INT) + BDESC_END (SPECIAL_ARGS, PURE_ARGS) /* AVX */ diff --git a/gcc/config/i386/i386-c.cc b/gcc/config/i386/i386-c.cc index ac0087a4653..07ce0f8a5a7 100644 --- a/gcc/config/i386/i386-c.cc +++ b/gcc/config/i386/i386-c.cc @@ -657,6 +657,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__CMPCCXADD__"); if (isa_flag2 & OPTION_MASK_ISA2_AMX_FP16) def_or_undef (parse_in, "__AMX_FP16__"); + if (isa_flag2 & OPTION_MASK_ISA2_PREFETCHI) + def_or_undef (parse_in, "__PREFETCHI__"); if (TARGET_IAMCU) { def_or_undef (parse_in, "__iamcu"); diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index a37fde307d1..2e0d12c0108 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -13035,6 +13035,83 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, return target; } + case IX86_BUILTIN_PREFETCH: + { + arg0 = CALL_EXPR_ARG (exp, 0); // const void * + arg1 = CALL_EXPR_ARG (exp, 1); // const int + arg2 = CALL_EXPR_ARG (exp, 2); // const int + arg3 = CALL_EXPR_ARG (exp, 3); // const int + + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + op2 = expand_normal (arg2); + op3 = expand_normal (arg3); + + if (!CONST_INT_P (op1) || !CONST_INT_P (op2) || !CONST_INT_P (op3)) + { + error ("second, third and fourth argument must be a const"); + return const0_rtx; + } + + if (INTVAL (op3) == 1) + { + if (TARGET_64BIT + && local_func_symbolic_operand (op0, GET_MODE (op0))) + emit_insn (gen_prefetchi (op0, op2)); + else + { + warning (0, "instruction prefetch applies when in 64-bit mode" + " with RIP-relative addressing and" + " option %<-mprefetchi%>;" + " they stay NOPs otherwise"); + emit_insn (gen_nop ()); + } + } + else + { + if (!address_operand (op0, VOIDmode)) + { + op0 = convert_memory_address (Pmode, op0); + op0 = copy_addr_to_reg (op0); + } + emit_insn (gen_prefetch (op0, op1, op2)); + } + + return 0; + } + + case IX86_BUILTIN_PREFETCHI: + { + arg0 = CALL_EXPR_ARG (exp, 0); // const void * + arg1 = CALL_EXPR_ARG (exp, 1); // const int + + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + + if (!CONST_INT_P (op1)) + { + error ("second argument must be a const"); + return const0_rtx; + } + + /* GOT/PLT_PIC should not be available for instruction prefetch. + It must be real instruction address. */ + if (TARGET_64BIT + && local_func_symbolic_operand (op0, GET_MODE (op0))) + emit_insn (gen_prefetchi (op0, op1)); + else + { + /* Ignore the hint. */ + warning (0, "instruction prefetch applies when in 64-bit mode" + " with RIP-relative addressing and" + " option %<-mprefetchi%>;" + " they stay NOPs otherwise"); + emit_insn (gen_nop ()); + } + + return 0; + } + case IX86_BUILTIN_VEC_INIT_V2SI: case IX86_BUILTIN_VEC_INIT_V4HI: case IX86_BUILTIN_VEC_INIT_V8QI: diff --git a/gcc/config/i386/i386-isa.def b/gcc/config/i386/i386-isa.def index 55b25763957..f234dcc37d7 100644 --- a/gcc/config/i386/i386-isa.def +++ b/gcc/config/i386/i386-isa.def @@ -114,3 +114,4 @@ DEF_PTA(AVXVNNIINT8) DEF_PTA(AVXNECONVERT) DEF_PTA(CMPCCXADD) DEF_PTA(AMX_FP16) +DEF_PTA(PREFETCHI) diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index 2c16dc0cf96..e04b8407b62 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -233,7 +233,8 @@ static struct ix86_target_opts isa2_opts[] = { "-mavxvnniint8", OPTION_MASK_ISA2_AVXVNNIINT8 }, { "-mavxneconvert", OPTION_MASK_ISA2_AVXNECONVERT }, { "-mcmpccxadd", OPTION_MASK_ISA2_CMPCCXADD }, - { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 } + { "-mamx-fp16", OPTION_MASK_ISA2_AMX_FP16 }, + { "-mprefetchi", OPTION_MASK_ISA2_PREFETCHI } }; static struct ix86_target_opts isa_opts[] = { @@ -1082,6 +1083,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("avxneconvert", OPT_mavxneconvert), IX86_ATTR_ISA ("cmpccxadd", OPT_mcmpccxadd), IX86_ATTR_ISA ("amx-fp16", OPT_mamx_fp16), + IX86_ATTR_ISA ("prefetchi", OPT_mprefetchi), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 436eabb691a..a2b8f26714a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -330,6 +330,9 @@ ;; For HRESET support UNSPECV_HRESET + + ;; For PREFETCHI support + UNSPECV_PREFETCHI ]) ;; Constants to represent rounding modes in the ROUND instruction @@ -23961,6 +23964,26 @@ (symbol_ref "memory_address_length (operands[0], false)")) (set_attr "memory" "none")]) +(define_insn "prefetchi" + [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p") + (match_operand:SI 1 "const_int_operand")] + UNSPECV_PREFETCHI)] + "TARGET_PREFETCHI && TARGET_64BIT" +{ + static const char * const patterns[2] = { + "prefetchit1\t%0", "prefetchit0\t%0" + }; + + int locality = INTVAL (operands[1]); + gcc_assert (IN_RANGE (locality, 2, 3)); + + return patterns[locality - 2]; +} + [(set_attr "type" "sse") + (set (attr "length_address") + (symbol_ref "memory_address_length (operands[0], false)")) + (set_attr "memory" "none")]) + (define_expand "stack_protect_set" [(match_operand 0 "memory_operand") (match_operand 1 "memory_operand")] diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index eaa43946341..1d91103cd54 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1238,3 +1238,7 @@ CMPCCXADD build-in functions and code generation. mamx-fp16 Target Mask(ISA2_AMX_FP16) Var(ix86_isa_flags2) Save Support AMX-FP16 built-in functions and code generation. + +mprefetchi +Target Mask(ISA2_PREFETCHI) Var(ix86_isa_flags2) Save +Support PREFETCHI built-in functions and code generation. diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index c4141a96735..2a3f07224cc 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -610,6 +610,21 @@ return false; }) +(define_predicate "local_func_symbolic_operand" + (match_operand 0 "local_symbolic_operand") +{ + if (GET_CODE (op) == CONST + && GET_CODE (XEXP (op, 0)) == PLUS + && CONST_INT_P (XEXP (XEXP (op, 0), 1))) + op = XEXP (XEXP (op, 0), 0); + + if (GET_CODE (op) == SYMBOL_REF + && !SYMBOL_REF_FUNCTION_P (op)) + return false; + + return true; +}) + ;; Test for a legitimate @GOTOFF operand. ;; ;; VxWorks does not impose a fixed gap between segments; the run-time diff --git a/gcc/config/i386/prfchiintrin.h b/gcc/config/i386/prfchiintrin.h new file mode 100644 index 00000000000..06deef488ba --- /dev/null +++ b/gcc/config/i386/prfchiintrin.h @@ -0,0 +1,49 @@ +/* Copyright (C) 2022 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#if !defined _X86GPRINTRIN_H_INCLUDED +# error "Never use <prfchiintrin.h> directly; include <x86gprintrin.h> instead." +#endif + +#ifndef _PRFCHIINTRIN_H_INCLUDED +#define _PRFCHIINTRIN_H_INCLUDED + +#ifdef __x86_64__ + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_m_prefetchit0 (void* __P) +{ + __builtin_ia32_prefetchi (__P, 3); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_m_prefetchit1 (void* __P) +{ + __builtin_ia32_prefetchi (__P, 2); +} + +#endif + +#endif /* _PRFCHIINTRIN_H_INCLUDED */ diff --git a/gcc/config/i386/x86gprintrin.h b/gcc/config/i386/x86gprintrin.h index a84fbe9137d..abe8f487f03 100644 --- a/gcc/config/i386/x86gprintrin.h +++ b/gcc/config/i386/x86gprintrin.h @@ -74,6 +74,8 @@ #include <pkuintrin.h> +#include <prfchiintrin.h> + #include <rdseedintrin.h> #include <rtmintrin.h> diff --git a/gcc/config/i386/xmmintrin.h b/gcc/config/i386/xmmintrin.h index 62659080601..ab65c430a97 100644 --- a/gcc/config/i386/xmmintrin.h +++ b/gcc/config/i386/xmmintrin.h @@ -36,6 +36,8 @@ /* Constants for use with _mm_prefetch. */ enum _mm_hint { + _MM_HINT_IT0 = 19, + _MM_HINT_IT1 = 18, /* _MM_HINT_ET is _MM_HINT_T with set 3rd bit. */ _MM_HINT_ET0 = 7, _MM_HINT_ET1 = 6, @@ -51,11 +53,12 @@ enum _mm_hint extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_prefetch (const void *__P, enum _mm_hint __I) { - __builtin_prefetch (__P, (__I & 0x4) >> 2, __I & 0x3); + __builtin_ia32_prefetch (__P, (__I & 0x4) >> 2, + __I & 0x3, (__I & 0x10) >> 4); } #else #define _mm_prefetch(P, I) \ - __builtin_prefetch ((P), ((I & 0x4) >> 2), (I & 0x3)) + __builtin_ia32_prefetch ((P), ((I) & 0x4) >> 2, ((I) & 0x3), ((I) & 0x10) >> 4) #endif #ifndef __SSE__ |