From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yb1-xb2f.google.com (mail-yb1-xb2f.google.com [IPv6:2607:f8b0:4864:20::b2f]) by sourceware.org (Postfix) with ESMTPS id 98AC03852C70 for ; Mon, 12 Dec 2022 21:41:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 98AC03852C70 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-yb1-xb2f.google.com with SMTP id s11so15398721ybe.2 for ; Mon, 12 Dec 2022 13:41:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=DdYLgoXydN+zrKIR1q8xKPEv34hBp6pp1CI5joK4uQM=; b=adtM4Iiqzhx5HUHdqW4ZApFqm084pE58nn1qWvE1exNoydi7Gy8dgChpHKYI/VTor1 mGHCueSAxzhiRiy1Fl854gG2aM3HVQkw/TvdNfnOkM4rwJIHLN74FroE9O99c67vmKBq PYMrh9RKCAqoQn+9XyePU/PL834cxEPWFRqttV/xlliawRMo2EK/Fty7bG4KIZEypdsA xxU//bpdcDYPpYB53U8QtpRefD3iLGP4g4SSKdHRdXORFMWAtfvkdykw1H0e/XGOi/Ql QuJS1EzBybMMYhNVV6owRIyXMFIYexe2USAI62qkEGKNDiG7PgDCrMBAl8Cw8KFX7Rjz P98g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=DdYLgoXydN+zrKIR1q8xKPEv34hBp6pp1CI5joK4uQM=; b=qwlR5WBxOLUWDRwBbwKVkQCTLg7T7YyZ1ocy1sKAxvL5gY0kOrG+LCWsqcdxMRTzx1 uJY+IxFmbBlZpjsQKtnHjZKSV6BFAECEWHYYY7q1pVd4f+9KZ2WQGI/XpR0mZ3mokmtu LF2KL6Zh8xZAZ5t7hxFwYMdA/i7D+w6Ucdsgpe2IuJxbjheTYk44JlTUflPmwQ/Kx/yL 2X/73WhdW38+3nT7VPtF7x5O3oqTitX4m1Mh1W69vxO39W5iMXGrHB8LD2J4+58bi8+s lW2Xv3bNZU1sVitvQTwr7QHCEPjEeZm1GZnZljJfClvmuY+X20e8wXoWDAH6H6Jv1DNV autA== X-Gm-Message-State: ANoB5plM68VIbMcpouk1cQ6doE/KHPMuvHvcohC+k+tqPdM06XjQrN2t sm5WG2P7SAzBfH2ZHBrljS7RUBxC6RuMOX96Kyc= X-Google-Smtp-Source: AA0mqf7cp/HoXehIrr6Dl77l8pjsUozoX7JUSq8PDeRXIhElc48oBJrGjFH/MrKEboGhj1Cxvy/nKX3u45Xrrx4BLyY= X-Received: by 2002:a25:ae09:0:b0:700:bafb:250f with SMTP id a9-20020a25ae09000000b00700bafb250fmr19785413ybj.136.1670881294589; Mon, 12 Dec 2022 13:41:34 -0800 (PST) MIME-Version: 1.0 References: <8e489785-b181-fbcf-e029-cd75796a6f28@ispras.ru> <27b06e9f-1e80-585d-624e-6f50475a5aa8@ispras.ru> In-Reply-To: From: =?UTF-8?B?SmFuIEh1YmnEjWth?= Date: Mon, 12 Dec 2022 22:41:23 +0100 Message-ID: Subject: Re: [PATCH][X86_64] Separate znver4 insn reservations from older znvers To: "Joshi, Tejas Sanjay" Cc: Alexander Monakov , "gcc-patches@gcc.gnu.org" , "Kumar, Venkataramanan" Content-Type: multipart/alternative; boundary="00000000000006a92f05efa85e35" X-Spam-Status: No, score=-6.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,HTML_MESSAGE,KAM_SHORT,RCVD_IN_DNSWL_NONE,SCC_5_SHORT_WORD_LINES,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --00000000000006a92f05efa85e35 Content-Type: text/plain; charset="UTF-8" > I have addressed all your comments in this revised patch, PFA and inlined > below. > > Is it ok for trunk? > > Thanks and Regards, > Tejas > > gcc/ChangeLog: > > * gcc/common/config/i386/i386-common.cc (processor_alias_table): > Use CPU_ZNVER4 for znver4. > * config/i386/i386.md: Add znver4.md. > * config/i386/znver4.md: New. > Hi, I went through the patch and compared with Agner's table and have few comments below. > > --- > gcc/common/config/i386/i386-common.cc | 2 +- > gcc/config/i386/i386.md | 1 + > gcc/config/i386/znver4.md | 1027 +++++++++++++++++++++++++ > 3 files changed, 1029 insertions(+), 1 deletion(-) > create mode 100644 gcc/config/i386/znver4.md > > diff --git a/gcc/common/config/i386/i386-common.cc > b/gcc/common/config/i386/i386-common.cc > index 6ce2a588adc..6d941642911 100644 > --- a/gcc/common/config/i386/i386-common.cc > +++ b/gcc/common/config/i386/i386-common.cc > @@ -2207,7 +2207,7 @@ const pta processor_alias_table[] = > {"znver3", PROCESSOR_ZNVER3, CPU_ZNVER3, > PTA_ZNVER3, > M_CPU_SUBTYPE (AMDFAM19H_ZNVER3), P_PROC_AVX2}, > - {"znver4", PROCESSOR_ZNVER4, CPU_ZNVER3, > + {"znver4", PROCESSOR_ZNVER4, CPU_ZNVER4, > PTA_ZNVER4, > M_CPU_SUBTYPE (AMDFAM19H_ZNVER4), P_PROC_AVX512F}, > {"btver1", PROCESSOR_BTVER1, CPU_GENERIC, > diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md > index 01faa911b77..ebb4eec1961 100644 > --- a/gcc/config/i386/i386.md > +++ b/gcc/config/i386/i386.md > @@ -1318,6 +1318,7 @@ > (include "bdver3.md") > (include "btver2.md") > (include "znver.md") > +(include "znver4.md") > (include "geode.md") > (include "atom.md") > (include "slm.md") > diff --git a/gcc/config/i386/znver4.md b/gcc/config/i386/znver4.md > new file mode 100644 > index 00000000000..9d52dc517f5 > --- /dev/null > +++ b/gcc/config/i386/znver4.md > @@ -0,0 +1,1027 @@ > +;; Copyright (C) 2012-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. > +;; > +;; You should have received a copy of the GNU General Public License > +;; along with GCC; see the file COPYING3. If not see > +;; . > +;; > + > + > +(define_attr "znver4_decode" "direct,vector,double" > + (const_string "direct")) > + > +;; AMD znver4 Scheduling > +;; Modeling automatons for zen decoders, integer execution pipes, > +;; AGU pipes, branch, floating point execution and fp store units. > +(define_automaton "znver4, znver4_ieu, znver4_idiv, znver4_fdiv, > znver4_agu, znver4_bru, znver4_fpu, znver4_fp_store") > + > +;; Decoders unit has 4 decoders and all of them can decode fast path > +;; and vector type instructions. > +(define_cpu_unit "znver4-decode0" "znver4") > +(define_cpu_unit "znver4-decode1" "znver4") > +(define_cpu_unit "znver4-decode2" "znver4") > +(define_cpu_unit "znver4-decode3" "znver4") > + > +;; Currently blocking all decoders for vector path instructions as > +;; they are dispatched separetely as microcode sequence. > +(define_reservation "znver4-vector" > "znver4-decode0+znver4-decode1+znver4-decode2+znver4-decode3") > + > +;; Direct instructions can be issued to any of the four decoders. > +(define_reservation "znver4-direct" > "znver4-decode0|znver4-decode1|znver4-decode2|znver4-decode3") > + > +;; Fix me: Need to revisit this later to simulate fast path double > behavior. > +(define_reservation "znver4-double" "znver4-direct") > + > + > +;; Integer unit 4 ALU pipes. > +(define_cpu_unit "znver4-ieu0" "znver4_ieu") > +(define_cpu_unit "znver4-ieu1" "znver4_ieu") > +(define_cpu_unit "znver4-ieu2" "znver4_ieu") > +(define_cpu_unit "znver4-ieu3" "znver4_ieu") > +(define_reservation "znver4-ieu" > "znver4-ieu0|znver4-ieu1|znver4-ieu2|znver4-ieu3") > + > +;; 3 AGU pipes in znver4 > +(define_cpu_unit "znver4-agu0" "znver4_agu") > +(define_cpu_unit "znver4-agu1" "znver4_agu") > +(define_cpu_unit "znver4-agu2" "znver4_agu") > +(define_reservation "znver4-agu-reserve" > "znver4-agu0|znver4-agu1|znver4-agu2") > + > +;; Load is 4 cycles. We do not model reservation of load unit. > +(define_reservation "znver4-load" "znver4-agu-reserve") > +(define_reservation "znver4-store" "znver4-agu-reserve") > + > +;; vectorpath (microcoded) instructions are single issue instructions. > +;; So, they occupy all the integer units. > +(define_reservation "znver4-ivector" "znver4-ieu0+znver4-ieu1 > + +znver4-ieu2+znver4-ieu3 > + > +znver4-agu0+znver4-agu1+znver4-agu2") > + > +;; Floating point unit 4 FP pipes. > +(define_cpu_unit "znver4-fpu0" "znver4_fpu") > +(define_cpu_unit "znver4-fpu1" "znver4_fpu") > +(define_cpu_unit "znver4-fpu2" "znver4_fpu") > +(define_cpu_unit "znver4-fpu3" "znver4_fpu") > + > +(define_reservation "znver4-fpu" > "znver4-fpu0|znver4-fpu1|znver4-fpu2|znver4-fpu3") > + > +(define_reservation "znver4-fvector" "znver4-fpu0+znver4-fpu1 > + +znver4-fpu2+znver4-fpu3 > + > +znver4-agu0+znver4-agu1+znver4-agu2") > + > +;; DIV units > +(define_cpu_unit "znver4-idiv" "znver4_idiv") > +(define_cpu_unit "znver4-fdiv" "znver4_fdiv") > + > +;; znver4 has a separate branch unit. > +(define_cpu_unit "znver4-bru" "znver4_bru") > So this unit is new since znver2 model. Rest of stuff above is the same, right? > + > +;; Separate fp store and fp-to-int store. Although there are 2 store > pipes, the > +;; throughput is limited to only one per cycle. > +(define_cpu_unit "znver4-fp-store" "znver4_fp_store") > + > +;; Call Instruction > +(define_insn_reservation "znver4_call" 1 > + (and (eq_attr "cpu" "znver4") > + (eq_attr "type" "call,callv")) > + > "znver4-double,znver4-ieu0|znver4-bru,znver4-store") > Perhaps this should be znver4-ieu0+znver4-bru to model the fact that call uses the branch unit? Also using | for things from different units is not really working as expected since in independent automatons we will end up chosing to not reserve anything. > + > +;; Push Instruction > +(define_insn_reservation "znver4_push" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "push") > + (eq_attr "memory" "store"))) > + "znver4-direct,znver4-store") > + > +(define_insn_reservation "znver4_push_load" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "push") > + (eq_attr "memory" "both"))) > + "znver4-direct,znver4-load,znver4-store") > Here we have 5 cycles instead of 4 for push. However reservations wise we do cycle 0 - direct cycle 1 - load cycle 2 - store and nothing in remaining two cycles. > + > +;; Pop instruction > +(define_insn_reservation "znver4_pop" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "pop") > + (eq_attr "memory" "load"))) > + "znver4-direct,znver4-load") > + > +(define_insn_reservation "znver4_pop_mem" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "pop") > + (eq_attr "memory" "both"))) > + "znver4-direct,znver4-load,znver4-store") > Similar situation here. I remember that at znver1 time I had problem with defining load as 4-cycle operation since the model got too large. This is probably artifact of that. I wonder if with the separation of division from the main model this still causes troubles... > + > +;; Leave > +(define_insn_reservation "znver4_leave" 1 > + (and (eq_attr "cpu" "znver4") > + (eq_attr "type" "leave")) > + "znver4-double,znver4-ieu,znver4-store") > + > +;; Integer Instructions or General instructions > +;; Multiplications > +(define_insn_reservation "znver4_imul" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "imul") > + (and (eq_attr "mode" "QI,HI,SI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-ieu1") > + > +(define_insn_reservation "znver4_imul_DI" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "imul") > + (and (eq_attr "mode" "DI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-ieu1") > Note that Agner Fog's tables claims znver4 imul to be still 3 cycles even for 64bit.. + > > +(define_insn_reservation "znver4_imov_direct_store" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "imov") > + (eq_attr "memory" "store"))) > + "znver4-direct,znver4-ieu,znver4-store") > + > +(define_insn_reservation "znver4_imov_load_double_store" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "double") > + (and (eq_attr "type" "imovx") > + (eq_attr "memory" "store")))) > + > "znver4-double,znver4-load,znver4-ieu,znver4-store") > + > +(define_insn_reservation "znver4_imov_load_direct_store" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "imov") > + (eq_attr "memory" "store"))) > + > "znver4-direct,znver4-load,znver4-ieu,znver4-store") > I wonder why znver4-load is here when memory is "store"? > + > +;; INTEGER/GENERAL Instructions > +(define_insn_reservation "znver4_insn2_load" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "icmov,setcc") > + (eq_attr "memory" "load"))) > + > "znver4-direct,znver4-load,znver4-ieu0|znver4-ieu3") > + > + > +(define_insn_reservation "znver4_insn2_store" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "icmov,setcc") > + (eq_attr "memory" "load"))) > + > "znver4-direct,znver4-ieu0|znver4-ieu3,znver4-store") > This looks like bug to me that is cut&pasted few times. Stores should test memory for "store" otherwise it is identical to reservation above. > + > +;; Other vector type > +(define_insn_reservation "znver4_ieu_vector" 5 > + (and (eq_attr "cpu" "znver4") > + (eq_attr "type" "other,multi")) > + "znver4-vector,znver4-ivector") > znvermodel tests also for str. Store and both is handled earlier but what about loads? > + > +;; alu1 instructions > +(define_insn_reservation "znver4_alu1_vector" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "vector") > + (and (eq_attr "type" "alu1") > + (eq_attr "memory" > "none,unknown")))) > + "znver4-vector,znver4-ivector") > + > +(define_insn_reservation "znver4_alu1_direct" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "direct") > + (and (eq_attr "type" "alu1") > + (eq_attr "memory" > "none,unknown")))) > + "znver4-direct,znver4-ieu") > + > +;; Branches > +(define_insn_reservation "znver4_branch" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ibr") > + (eq_attr "memory" "none"))) > + "znver4-direct,znver4-ieu0|znver4-bru") > Probably + insead of | > + > +(define_insn_reservation "znver4_branch_mem" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ibr") > + (eq_attr "memory" "load"))) > + "znver4-vector,znver4-ivector") > No bru use here? > + > +;; LEA instruction with simple addressing > +(define_insn_reservation "znver4_lea" 1 > + (and (eq_attr "cpu" "znver4") > + (eq_attr "type" "lea")) > + "znver4-direct,znver4-ieu") > + > +;; Floating Point > +;; FP movs > +(define_insn_reservation "znver4_fp_cmov" 6 > + (and (eq_attr "cpu" "znver4") > + (eq_attr "type" "fcmov")) > + "znver4-vector,znver4-fvector") > Agner Fog claims 4 cycles here. > +(define_insn_reservation "znver4_fp_mov_direct_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "direct") > + (and (eq_attr "type" "fmov") > + (eq_attr "memory" "load")))) > + "znver4-direct,znver4-load,znver4-fpu1") > 7 cycles in Agner Fog's manual > + > +(define_insn_reservation "znver4_fp_mov_direct_store" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "direct") > + (and (eq_attr "type" "fmov") > + (eq_attr "memory" "store")))) > + "znver4-direct,znver4-fpu1,znver4-fp-store") > 6 by Agner Fog > + > +(define_insn_reservation "znver4_fp_mov_double" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "double") > + (and (eq_attr "type" "fmov") > + (eq_attr "memory" "none")))) > + "znver4-double,znver4-fpu1,znver4-fp-store") > I wonder what this matches. > + > +(define_insn_reservation "znver4_fp_mov_double_load" 12 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "znver1_decode" "double") > + (and (eq_attr "type" "fmov") > + (eq_attr "memory" "load")))) > + > "znver4-double,znver4-load,znver4-fpu1,znver4-fp-store") > It seems that fild is modeled as fmov and double decode, but Agner Fog claims it is single decode with latency 13. > +;; FADD, FSUB, FMUL > +(define_insn_reservation "znver4_fp_op_mul" 6 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "fop,fmul") > + (eq_attr "memory" "none"))) > + "znver4-direct,znver4-fpu0") > 7 by Agner Fog > + > +;; AVX instructions > +(define_insn_reservation "znver4_sse_log" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog") > + (and (eq_attr "mode" > "V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu") > + > +(define_insn_reservation "znver4_sse_log_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog") > + (and (eq_attr "mode" > "V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "load")))) > + "znver4-direct,znver4-load,znver4-fpu") > Agner fog lists sse load as 5 cycles, so I wonder if it is right for operation to be 8 instead of 6? > + > +(define_insn_reservation "znver4_sse_log1" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog1") > + (and (eq_attr "mode" > "V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "none")))) > + > "znver4-direct,znver4-fpu1|znver4-fpu2,znver4-fp-store") > So logical operations take store unit even if they are not storing? > + > +(define_insn_reservation "znver4_sse_log1_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog1") > + (and (eq_attr "mode" > "V4SF,V8SF,V2DF,V4DF,QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1|znver4-fpu2,znver4-fp-store") > + > +(define_insn_reservation "znver4_sse_comi" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecomi") > + (eq_attr "memory" "none"))) > + > "znver4-double,znver4-fpu2|znver4-fpu3,znver4-fp-store") > + > +(define_insn_reservation "znver4_sse_comi_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecomi") > + (eq_attr "memory" "load"))) > + > "znver4-double,znver4-load,znver4-fpu2|znver4-fpu3,znver4-fp-store") > + > +(define_insn_reservation "znver4_sse_test" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "prefix_extra" "1") > + (and (eq_attr "type" "ssecomi") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu1|znver4-fpu2") > + > +(define_insn_reservation "znver4_sse_test_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "prefix_extra" "1") > + (and (eq_attr "type" "ssecomi") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1|znver4-fpu2") > + > +(define_insn_reservation "znver4_sse_imul" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseimul") > + (and (eq_attr "mode" > "QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu0|znver4-fpu3") > + > +(define_insn_reservation "znver4_sse_imul_load" 10 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseimul") > + (and (eq_attr "mode" > "QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0|znver4-fpu1") > + > +(define_insn_reservation "znver4_sse_mov" 2 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemov") > + (and (eq_attr "mode" > "QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu1|znver4-fpu2") > I think this is copied from znver1 table. It should be 1 cycle and often 0 if renaming happens? > + > +(define_insn_reservation "znver4_sse_mov_load" 9 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemov") > + (and (eq_attr "mode" > "QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1|znver4-fpu2") > 5 cycles Agner Fog > + > +(define_insn_reservation "znver4_sse_mov_store" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemov") > + (and (eq_attr "mode" > "QI,HI,SI,DI,TI,OI") > + (eq_attr "memory" "store")))) > + > "znver4-direct,znver4-fpu1|znver4-fpu2,znver4-fp-store") > We model other stores as 1 cycle operation, why you use 5 here? Also it seems that normal store is 1 op, so why it needs fpu? > +(define_insn_reservation "znver4_sse_add1" 6 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseadd1") > + (and (eq_attr "mode" > "V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF") > + (eq_attr "memory" "none")))) > + "znver4-vector,znver4-fvector") > This seems to match hadd that is listed as 4 cycles in Agner Fog. Why it is vector decode? > + > +(define_insn_reservation "znver4_sse_add1_load" 13 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseadd1") > + (and (eq_attr "mode" > "V8SF,V4DF,V4SF,V2DF,V2SF,V1DF,SF") > + (eq_attr "memory" "load")))) > + "znver4-vector,znver4-load,znver4-fvector") > Similarly here. > +(define_insn_reservation "znver4_sse_cmp_avx" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecmp,ssecomi") > + (and (eq_attr "mode" > "V4SF,V2DF,V2SF,V1DF,SF,QI,HI,SI,DI,TI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu0|znver4-fpu1") > + > +(define_insn_reservation "znver4_sse_cmp_avx_load" 10 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecmp,ssecomi") > + (and (eq_attr "mode" > "V4SF,V2DF,V2SF,V1DF,SF,QI,HI,SI,DI,TI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0|znver4-fpu1") > + > +(define_insn_reservation "znver4_sse_cmp_avx2" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecmp,ssecomi") > + (and (eq_attr "mode" "V8SF,V4DF,OI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu0|znver4-fpu1") > Is there really differnece between 128bit and 256bit here? +;; AVX512 instructions > > +(define_insn_reservation "znver4_sse_log_evex" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog") > + (and (eq_attr "mode" "V16SF,V8DF,XI") > + (eq_attr "memory" "none")))) > + > "znver4-direct,znver4-fpu0*2|znver4-fpu1*2|znver4-fpu2*2|znver4-fpu3*2") > I think the instruction does two operaitos in parallel so (znver4-fpu0+znver4-fpu1)|(znver4-fpu1+znver4-fpu2)|(znver4-fpu0+znver4-fpu2) > + > +(define_insn_reservation "znver4_sse_log_evex_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog") > + (and (eq_attr "mode" "V16SF,V8DF,XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2|znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_log1_evex" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog1") > + (and (eq_attr "mode" "V16SF,V8DF,XI") > + (eq_attr "memory" "none")))) > + > "znver4-direct,znver4-fpu1*2|znver4-fpu2*2,znver4-fp-store") > + > +(define_insn_reservation "znver4_sse_log1_evex_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sselog1") > + (and (eq_attr "mode" "V16SF,V8DF,XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1*2|znver4-fpu2*2,znver4-fp-store") > + > +(define_insn_reservation "znver4_sse_mul_evex" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemul") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_mul_evex_load" 10 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemul") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_imul_evex" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseimul") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu0*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_imul_evex_load" 10 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseimul") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_mov_evex" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemov") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu1*2|znver4-fpu2*2") > + > +(define_insn_reservation "znver4_sse_mov_evex_load" 11 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemov") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1*2|znver4-fpu2*2") > + > +(define_insn_reservation "znver4_sse_mov_evex_store" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemov") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "store")))) > + > "znver4-direct,znver4-fpu1*2|znver4-fpu2*2,znver4-fp-store") > + > +(define_insn_reservation "znver4_sse_add_evex" 3 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseadd") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_add_evex_load" 10 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseadd") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_iadd_evex" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseiadd") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "none")))) > + > "znver4-direct,znver4-fpu0*2|znver4-fpu1*2|znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_iadd_evex_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseiadd") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2|znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_div_pd_evex" 13 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssediv") > + (and (eq_attr "mode" "V8DF") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fdiv*9") > + > +(define_insn_reservation "znver4_sse_div_ps_evex" 10 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssediv") > + (and (eq_attr "mode" "V16SF") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fdiv*6") > + > +(define_insn_reservation "znver4_sse_div_pd_evex_load" 20 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssediv") > + (and (eq_attr "mode" "V8DF") > + (eq_attr "memory" "load")))) > + "znver4-direct,znver4-load,znver4-fdiv*9") > + > +(define_insn_reservation "znver4_sse_div_ps_evex_load" 17 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssediv") > + (and (eq_attr "mode" "V16SF") > + (eq_attr "memory" "load")))) > + "znver4-direct,znver4-load,znver4-fdiv*6") > + > +(define_insn_reservation "znver4_sse_cmp_avx512" 5 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecmp,ssecomi") > + (and (eq_attr "mode" "V16SF,V8DF,XI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_cmp_avx512_load" 12 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecmp,ssecomi") > + (and (eq_attr "mode" "V16SF,V8DF,XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_cvt_evex" 6 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecvt") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "none")))) > + > "znver4-direct,znver4-fpu1*2|znver4-fpu2*2,znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_cvt_evex_load" 13 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssecvt") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1*2|znver4-fpu2*2,znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_shuf_evex" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseshuf") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "none")))) > + > "znver4-direct,znver4-fpu0*2|znver4-fpu1*2|znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_shuf_evex_load" 8 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseshuf") > + (and (eq_attr "mode" "V16SF,V8DF") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2|znver4-fpu2*2|znver4-fpu3*2") > + > +(define_insn_reservation "znver4_sse_ishuf_evex" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseshuf") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "none")))) > + "znver4-direct,znver4-fpu1*2|znver4-fpu2*2") > + > +(define_insn_reservation "znver4_sse_ishuf_evex_load" 11 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseshuf") > + (and (eq_attr "mode" "XI") > + (eq_attr "memory" "load")))) > + > "znver4-direct,znver4-load,znver4-fpu1*2|znver4-fpu2*2") > + > +(define_insn_reservation "znver4_sse_muladd" 4 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "ssemuladd") > + (eq_attr "memory" "none"))) > + "znver4-direct,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_muladd_load" 11 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "sseshuf") > + (eq_attr "memory" "load"))) > + > "znver4-direct,znver4-load,znver4-fpu0*2|znver4-fpu1*2") > + > +;; AVX512 mask instructions > + > +(define_insn_reservation "znver4_sse_mskmov" 2 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "mskmov") > + (eq_attr "memory" "none"))) > + "znver4-direct,znver4-fpu0*2|znver4-fpu1*2") > + > +(define_insn_reservation "znver4_sse_msklog" 1 > + (and (eq_attr "cpu" "znver4") > + (and (eq_attr "type" "msklog") > + (eq_attr "memory" "none"))) > + "znver4-direct,znver4-fpu2*2|znver4-fpu3*2") > Honza --00000000000006a92f05efa85e35--