On Tue, May 8, 2018 at 1:34 PM, Peryt, Sebastian <sebastian.pe...@intel.com> wrote: > Hi, > > This patch adds support for WAITPKG instructions. > > Is it ok for trunk and after few day for backport to GCC-8? > > 2018-05-08 Sebastian Peryt <sebastian.pe...@intel.com> > > gcc/ > > * common/config/i386/i386-common.c (OPTION_MASK_ISA_WAITPKG_SET, > OPTION_MASK_ISA_WAITPKG_UNSET): New defines. > (ix86_handle_option): Handle -mwaitpkg. > * config.gcc: New header. > * config/i386/cpuid.h (bit_WAITPKG): New bit. > * config/i386/driver-i386.c (host_detect_local_cpu): Detect -mwaitpkg. > * config/i386/i386-builtin-types.def ((UINT8, UNSIGNED, UINT64)): New > function type. > * config/i386/i386-c.c (ix86_target_macros_internal): Handle > OPTION_MASK_ISA_WAITPKG > * config/i386/i386.c (ix86_target_string): Added -mwaitpkg. > (ix86_option_override_internal): Added PTA_WAITPKG. > (ix86_valid_target_attribute_inner_p): Added -mwaitpkg. > (enum ix86_builtins): Added IX86_BUILTIN_UMONITOR, > IX86_BUILTIN_UMWAIT, > IX86_BUILTIN_TPAUSE. > (ix86_init_mmx_sse_builtins): Define __builtin_ia32_umonitor, > __builtin_ia32_umwait and __builtin_ia32_tpause. > (ix86_expand_builtin):Expand IX86_BUILTIN_UMONITOR, > IX86_BUILTIN_UMWAIT, IX86_BUILTIN_TPAUSE. > * config/i386/i386.h (TARGET_WAITPKG, TARGET_WAITPKG_P): New. > * config/i386/i386.opt: Added -mwaitpkg. > * config/i386/sse.md (UNSPECV_UMWAIT, UNSPECV_UMONITOR, > UNSPECV_TPAUSE): New. > (umwait, umonitor_<mode>, tpause): New. > * config/i386/waitpkgintrin.h: New file. > * config/i386/x86intrin.h: New header. > * doc/invoke.texi: Added -mwaitpkg. > > 2018-05-08 Sebastian Peryt <sebastian.pe...@intel.com> > > gcc/testsuite/ > > * gcc.target/i386/tpause-1.c: New test. > * gcc.target/i386/umonitor-1.c: New test. > > Thanks, > Sebastian > >
+ case IX86_BUILTIN_UMONITOR: + arg0 = CALL_EXPR_ARG (exp, 0); + op0 = expand_normal (arg0); + if (!REG_P (op0)) + op0 = ix86_zero_extend_to_Pmode (op0); + + emit_insn (ix86_gen_umonitor (op0)); + return 0; Please see how movdir64b handles its address operand. Also, do not use global ix86_gen_monitor, just expand directly in the same way as movdir64b. + case IX86_BUILTIN_UMWAIT: + case IX86_BUILTIN_TPAUSE: + rtx eax, edx, op1_lo, op1_hi; + arg0 = CALL_EXPR_ARG (exp, 0); + arg1 = CALL_EXPR_ARG (exp, 1); + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + eax = gen_rtx_REG (SImode, AX_REG); + edx = gen_rtx_REG (SImode, DX_REG); + if (!REG_P (op0)) + op0 = copy_to_mode_reg (SImode, op0); + if (!REG_P (op1)) + op1 = copy_to_mode_reg (DImode, op1); + op1_lo = gen_lowpart (SImode, op1); + op1_hi = expand_shift (RSHIFT_EXPR, DImode, op1, + GET_MODE_BITSIZE (SImode), 0, 1); + op1_hi = convert_modes (SImode, DImode, op1_hi, 1); + emit_move_insn (eax, op1_lo); + emit_move_insn (edx, op1_hi); + emit_insn (fcode == IX86_BUILTIN_UMWAIT + ? gen_umwait (op0, eax, edx) + : gen_tpause (op0, eax, edx)); + + /* Return current CF value. */ + op3 = gen_rtx_REG (CCCmode, FLAGS_REG); + target = gen_rtx_LTU (QImode, op3, const0_rtx); + + return target; For the above code, please see how xsetbv expansion and patterns are handling their input operands. There should be two patterns, one for 32bit and the other for 64bit targets. The patterns will need to set FLAGS_REG, otherwise the test will be removed. +(define_insn "umwait" + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r") + (use (match_operand:SI 1 "register_operand" "a")) + (use (match_operand:SI 2 "register_operand" "d"))] + UNSPECV_UMWAIT)] + "TARGET_WAITPKG" + "umwait\t{%0}" + [(set_attr "length" "3")]) No need for "use" RTX here and in other patterns. You should also remove {} from insn template, otherwise there will be no operand printed in some asm dialect. Uros.