1 //=- X86ScheduleBtVer2.td - X86 BtVer2 (Jaguar) Scheduling ---*- tablegen -*-=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the machine model for AMD btver2 (Jaguar) to support 11 // instruction scheduling and other instruction cost heuristics. Based off AMD Software 12 // Optimization Guide for AMD Family 16h Processors & Instruction Latency appendix. 13 // 14 //===----------------------------------------------------------------------===// 15 16 def BtVer2Model : SchedMachineModel { 17 // All x86 instructions are modeled as a single micro-op, and btver2 can 18 // decode 2 instructions per cycle. 19 let IssueWidth = 2; 20 let MicroOpBufferSize = 64; // Retire Control Unit 21 let LoadLatency = 5; // FPU latency (worse case cf Integer 3 cycle latency) 22 let HighLatency = 25; 23 let MispredictPenalty = 14; // Minimum branch misdirection penalty 24 let PostRAScheduler = 1; 25 26 // FIXME: SSE4/AVX is unimplemented. This flag is set to allow 27 // the scheduler to assign a default model to unrecognized opcodes. 28 let CompleteModel = 0; 29 } 30 31 let SchedModel = BtVer2Model in { 32 33 // Jaguar can issue up to 6 micro-ops in one cycle 34 def JALU0 : ProcResource<1>; // Integer Pipe0: integer ALU0 (also handle FP->INT jam) 35 def JALU1 : ProcResource<1>; // Integer Pipe1: integer ALU1/MUL/DIV 36 def JLAGU : ProcResource<1>; // Integer Pipe2: LAGU 37 def JSAGU : ProcResource<1>; // Integer Pipe3: SAGU (also handles 3-operand LEA) 38 def JFPU0 : ProcResource<1>; // Vector/FPU Pipe0: VALU0/VIMUL/FPA 39 def JFPU1 : ProcResource<1>; // Vector/FPU Pipe1: VALU1/STC/FPM 40 41 // The Integer PRF for Jaguar is 64 entries, and it holds the architectural and 42 // speculative version of the 64-bit integer registers. 43 // Reference: www.realworldtech.com/jaguar/4/ 44 // 45 // The processor always keeps the different parts of an integer register 46 // together. An instruction that writes to a part of a register will therefore 47 // have a false dependence on any previous write to the same register or any 48 // part of it. 49 // Reference: Section 21.10 "AMD Bobcat and Jaguar pipeline: Partial register 50 // access" - Agner Fog's "microarchitecture.pdf". 51 def JIntegerPRF : RegisterFile<64, [GR64, CCR]>; 52 53 // The Jaguar FP Retire Queue renames SIMD and FP uOps onto a pool of 72 SSE 54 // registers. Operations on 256-bit data types are cracked into two COPs. 55 // Reference: www.realworldtech.com/jaguar/4/ 56 def JFpuPRF: RegisterFile<72, [VR64, VR128, VR256], [1, 1, 2]>; 57 58 // The retire control unit (RCU) can track up to 64 macro-ops in-flight. It can 59 // retire up to two macro-ops per cycle. 60 // Reference: "Software Optimization Guide for AMD Family 16h Processors" 61 def JRCU : RetireControlUnit<64, 2>; 62 63 // Integer Pipe Scheduler 64 def JALU01 : ProcResGroup<[JALU0, JALU1]> { 65 let BufferSize=20; 66 } 67 68 // AGU Pipe Scheduler 69 def JLSAGU : ProcResGroup<[JLAGU, JSAGU]> { 70 let BufferSize=12; 71 } 72 73 // Fpu Pipe Scheduler 74 def JFPU01 : ProcResGroup<[JFPU0, JFPU1]> { 75 let BufferSize=18; 76 } 77 78 // Functional units 79 def JDiv : ProcResource<1>; // integer division 80 def JMul : ProcResource<1>; // integer multiplication 81 def JVALU0 : ProcResource<1>; // vector integer 82 def JVALU1 : ProcResource<1>; // vector integer 83 def JVIMUL : ProcResource<1>; // vector integer multiplication 84 def JSTC : ProcResource<1>; // vector store/convert 85 def JFPM : ProcResource<1>; // FP multiplication 86 def JFPA : ProcResource<1>; // FP addition 87 88 // Functional unit groups 89 def JFPX : ProcResGroup<[JFPA, JFPM]>; 90 def JVALU : ProcResGroup<[JVALU0, JVALU1]>; 91 92 // Integer loads are 3 cycles, so ReadAfterLd registers needn't be available until 3 93 // cycles after the memory operand. 94 def : ReadAdvance<ReadAfterLd, 3>; 95 96 // Many SchedWrites are defined in pairs with and without a folded load. 97 // Instructions with folded loads are usually micro-fused, so they only appear 98 // as two micro-ops when dispatched by the schedulers. 99 // This multiclass defines the resource usage for variants with and without 100 // folded loads. 101 multiclass JWriteResIntPair<X86FoldableSchedWrite SchedRW, 102 list<ProcResourceKind> ExePorts, 103 int Lat, list<int> Res = [], int UOps = 1> { 104 // Register variant is using a single cycle on ExePort. 105 def : WriteRes<SchedRW, ExePorts> { 106 let Latency = Lat; 107 let ResourceCycles = Res; 108 let NumMicroOps = UOps; 109 } 110 111 // Memory variant also uses a cycle on JLAGU and adds 3 cycles to the 112 // latency. 113 def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> { 114 let Latency = !add(Lat, 3); 115 let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res)); 116 let NumMicroOps = UOps; 117 } 118 } 119 120 multiclass JWriteResFpuPair<X86FoldableSchedWrite SchedRW, 121 list<ProcResourceKind> ExePorts, 122 int Lat, list<int> Res = [], int UOps = 1> { 123 // Register variant is using a single cycle on ExePort. 124 def : WriteRes<SchedRW, ExePorts> { 125 let Latency = Lat; 126 let ResourceCycles = Res; 127 let NumMicroOps = UOps; 128 } 129 130 // Memory variant also uses a cycle on JLAGU and adds 5 cycles to the 131 // latency. 132 def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> { 133 let Latency = !add(Lat, 5); 134 let ResourceCycles = !if(!empty(Res), [], !listconcat([1], Res)); 135 let NumMicroOps = UOps; 136 } 137 } 138 139 multiclass JWriteResYMMPair<X86FoldableSchedWrite SchedRW, 140 list<ProcResourceKind> ExePorts, 141 int Lat, list<int> Res = [2], int UOps = 2> { 142 // Register variant is using a single cycle on ExePort. 143 def : WriteRes<SchedRW, ExePorts> { 144 let Latency = Lat; 145 let ResourceCycles = Res; 146 let NumMicroOps = UOps; 147 } 148 149 // Memory variant also uses 2 cycles on JLAGU and adds 5 cycles to the 150 // latency. 151 def : WriteRes<SchedRW.Folded, !listconcat([JLAGU], ExePorts)> { 152 let Latency = !add(Lat, 5); 153 let ResourceCycles = !listconcat([2], Res); 154 let NumMicroOps = UOps; 155 } 156 } 157 158 // A folded store needs a cycle on the SAGU for the store data. 159 def : WriteRes<WriteRMW, [JSAGU]>; 160 161 //////////////////////////////////////////////////////////////////////////////// 162 // Arithmetic. 163 //////////////////////////////////////////////////////////////////////////////// 164 165 defm : JWriteResIntPair<WriteALU, [JALU01], 1>; 166 defm : JWriteResIntPair<WriteADC, [JALU01], 1, [2]>; 167 defm : JWriteResIntPair<WriteIMul, [JALU1, JMul], 3, [1, 1], 2>; // i8/i16/i32 multiplication 168 defm : JWriteResIntPair<WriteIMul64, [JALU1, JMul], 6, [1, 4], 2>; // i64 multiplication 169 defm : X86WriteRes<WriteIMulH, [JALU1], 6, [4], 1>; 170 171 defm : X86WriteRes<WriteBSWAP32, [JALU01], 1, [1], 1>; 172 defm : X86WriteRes<WriteBSWAP64, [JALU01], 1, [1], 1>; 173 174 defm : JWriteResIntPair<WriteDiv8, [JALU1, JDiv], 12, [1, 12], 1>; 175 defm : JWriteResIntPair<WriteDiv16, [JALU1, JDiv], 17, [1, 17], 2>; 176 defm : JWriteResIntPair<WriteDiv32, [JALU1, JDiv], 25, [1, 25], 2>; 177 defm : JWriteResIntPair<WriteDiv64, [JALU1, JDiv], 41, [1, 41], 2>; 178 defm : JWriteResIntPair<WriteIDiv8, [JALU1, JDiv], 12, [1, 12], 1>; 179 defm : JWriteResIntPair<WriteIDiv16, [JALU1, JDiv], 17, [1, 17], 2>; 180 defm : JWriteResIntPair<WriteIDiv32, [JALU1, JDiv], 25, [1, 25], 2>; 181 defm : JWriteResIntPair<WriteIDiv64, [JALU1, JDiv], 41, [1, 41], 2>; 182 183 defm : JWriteResIntPair<WriteCRC32, [JALU01], 3, [4], 3>; 184 185 defm : JWriteResIntPair<WriteCMOV, [JALU01], 1>; // Conditional move. 186 defm : JWriteResIntPair<WriteCMOV2, [JALU01], 1>; // Conditional (CF + ZF flag) move. 187 defm : X86WriteRes<WriteFCMOV, [JFPU0, JFPA], 3, [1,1], 1>; // x87 conditional move. 188 def : WriteRes<WriteSETCC, [JALU01]>; // Setcc. 189 def : WriteRes<WriteSETCCStore, [JALU01,JSAGU]>; 190 def : WriteRes<WriteLAHFSAHF, [JALU01]>; 191 def : WriteRes<WriteBitTest,[JALU01]>; 192 193 // This is for simple LEAs with one or two input operands. 194 def : WriteRes<WriteLEA, [JALU01]>; 195 196 // Bit counts. 197 defm : JWriteResIntPair<WriteBSF, [JALU01], 5, [4], 8>; 198 defm : JWriteResIntPair<WriteBSR, [JALU01], 5, [4], 8>; 199 defm : JWriteResIntPair<WritePOPCNT, [JALU01], 1>; 200 defm : JWriteResIntPair<WriteLZCNT, [JALU01], 1>; 201 defm : JWriteResIntPair<WriteTZCNT, [JALU01], 2, [2]>; 202 203 // BMI1 BEXTR, BMI2 BZHI 204 defm : JWriteResIntPair<WriteBEXTR, [JALU01], 1>; 205 defm : X86WriteResPairUnsupported<WriteBZHI>; 206 207 //////////////////////////////////////////////////////////////////////////////// 208 // Integer shifts and rotates. 209 //////////////////////////////////////////////////////////////////////////////// 210 211 defm : JWriteResIntPair<WriteShift, [JALU01], 1>; 212 213 // SHLD/SHRD. 214 defm : X86WriteRes<WriteSHDrri, [JALU01], 3, [6], 6>; 215 defm : X86WriteRes<WriteSHDrrcl,[JALU01], 4, [8], 7>; 216 defm : X86WriteRes<WriteSHDmri, [JLAGU, JALU01], 9, [1, 22], 8>; 217 defm : X86WriteRes<WriteSHDmrcl,[JLAGU, JALU01], 9, [1, 22], 8>; 218 219 //////////////////////////////////////////////////////////////////////////////// 220 // Loads, stores, and moves, not folded with other operations. 221 //////////////////////////////////////////////////////////////////////////////// 222 223 def : WriteRes<WriteLoad, [JLAGU]> { let Latency = 5; } 224 def : WriteRes<WriteStore, [JSAGU]>; 225 def : WriteRes<WriteStoreNT, [JSAGU]>; 226 def : WriteRes<WriteMove, [JALU01]>; 227 228 // Load/store MXCSR. 229 // FIXME: These are copy and pasted from WriteLoad/Store. 230 def : WriteRes<WriteLDMXCSR, [JLAGU]> { let Latency = 5; } 231 def : WriteRes<WriteSTMXCSR, [JSAGU]>; 232 233 // Treat misc copies as a move. 234 def : InstRW<[WriteMove], (instrs COPY)>; 235 236 //////////////////////////////////////////////////////////////////////////////// 237 // Idioms that clear a register, like xorps %xmm0, %xmm0. 238 // These can often bypass execution ports completely. 239 //////////////////////////////////////////////////////////////////////////////// 240 241 def : WriteRes<WriteZero, []>; 242 243 //////////////////////////////////////////////////////////////////////////////// 244 // Branches don't produce values, so they have no latency, but they still 245 // consume resources. Indirect branches can fold loads. 246 //////////////////////////////////////////////////////////////////////////////// 247 248 defm : JWriteResIntPair<WriteJump, [JALU01], 1>; 249 250 //////////////////////////////////////////////////////////////////////////////// 251 // Special case scheduling classes. 252 //////////////////////////////////////////////////////////////////////////////// 253 254 def : WriteRes<WriteSystem, [JALU01]> { let Latency = 100; } 255 def : WriteRes<WriteMicrocoded, [JALU01]> { let Latency = 100; } 256 def : WriteRes<WriteFence, [JSAGU]>; 257 258 // Nops don't have dependencies, so there's no actual latency, but we set this 259 // to '1' to tell the scheduler that the nop uses an ALU slot for a cycle. 260 def : WriteRes<WriteNop, [JALU01]> { let Latency = 1; } 261 262 //////////////////////////////////////////////////////////////////////////////// 263 // Floating point. This covers both scalar and vector operations. 264 //////////////////////////////////////////////////////////////////////////////// 265 266 defm : X86WriteRes<WriteFLD0, [JFPU1, JSTC], 3, [1,1], 1>; 267 defm : X86WriteRes<WriteFLD1, [JFPU1, JSTC], 3, [1,1], 1>; 268 defm : X86WriteRes<WriteFLDC, [JFPU1, JSTC], 3, [1,1], 1>; 269 defm : X86WriteRes<WriteFLoad, [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>; 270 defm : X86WriteRes<WriteFLoadX, [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>; 271 defm : X86WriteRes<WriteFLoadY, [JLAGU, JFPU01, JFPX], 5, [1, 1, 1], 1>; 272 defm : X86WriteRes<WriteFMaskedLoad, [JLAGU, JFPU01, JFPX], 6, [1, 1, 2], 1>; 273 defm : X86WriteRes<WriteFMaskedLoadY, [JLAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>; 274 275 defm : X86WriteRes<WriteFStore, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>; 276 defm : X86WriteRes<WriteFStoreX, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>; 277 defm : X86WriteRes<WriteFStoreY, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>; 278 defm : X86WriteRes<WriteFStoreNT, [JSAGU, JFPU1, JSTC], 3, [1, 1, 1], 1>; 279 defm : X86WriteRes<WriteFStoreNTX, [JSAGU, JFPU1, JSTC], 3, [1, 1, 1], 1>; 280 defm : X86WriteRes<WriteFStoreNTY, [JSAGU, JFPU1, JSTC], 3, [2, 2, 2], 1>; 281 defm : X86WriteRes<WriteFMaskedStore, [JSAGU, JFPU01, JFPX], 6, [1, 1, 4], 1>; 282 defm : X86WriteRes<WriteFMaskedStoreY, [JSAGU, JFPU01, JFPX], 6, [2, 2, 4], 2>; 283 284 defm : X86WriteRes<WriteFMove, [JFPU01, JFPX], 1, [1, 1], 1>; 285 defm : X86WriteRes<WriteFMoveX, [JFPU01, JFPX], 1, [1, 1], 1>; 286 defm : X86WriteRes<WriteFMoveY, [JFPU01, JFPX], 1, [2, 2], 2>; 287 288 defm : X86WriteRes<WriteEMMS, [JFPU01, JFPX], 2, [1, 1], 1>; 289 290 defm : JWriteResFpuPair<WriteFAdd, [JFPU0, JFPA], 3>; 291 defm : JWriteResFpuPair<WriteFAddX, [JFPU0, JFPA], 3>; 292 defm : JWriteResYMMPair<WriteFAddY, [JFPU0, JFPA], 3, [2,2], 2>; 293 defm : X86WriteResPairUnsupported<WriteFAddZ>; 294 defm : JWriteResFpuPair<WriteFAdd64, [JFPU0, JFPA], 3>; 295 defm : JWriteResFpuPair<WriteFAdd64X, [JFPU0, JFPA], 3>; 296 defm : JWriteResYMMPair<WriteFAdd64Y, [JFPU0, JFPA], 3, [2,2], 2>; 297 defm : X86WriteResPairUnsupported<WriteFAdd64Z>; 298 defm : JWriteResFpuPair<WriteFCmp, [JFPU0, JFPA], 2>; 299 defm : JWriteResFpuPair<WriteFCmpX, [JFPU0, JFPA], 2>; 300 defm : JWriteResYMMPair<WriteFCmpY, [JFPU0, JFPA], 2, [2,2], 2>; 301 defm : X86WriteResPairUnsupported<WriteFCmpZ>; 302 defm : JWriteResFpuPair<WriteFCmp64, [JFPU0, JFPA], 2>; 303 defm : JWriteResFpuPair<WriteFCmp64X, [JFPU0, JFPA], 2>; 304 defm : JWriteResYMMPair<WriteFCmp64Y, [JFPU0, JFPA], 2, [2,2], 2>; 305 defm : X86WriteResPairUnsupported<WriteFCmp64Z>; 306 defm : JWriteResFpuPair<WriteFCom, [JFPU0, JFPA, JALU0], 3>; 307 defm : JWriteResFpuPair<WriteFMul, [JFPU1, JFPM], 2>; 308 defm : JWriteResFpuPair<WriteFMulX, [JFPU1, JFPM], 2>; 309 defm : JWriteResYMMPair<WriteFMulY, [JFPU1, JFPM], 2, [2,2], 2>; 310 defm : X86WriteResPairUnsupported<WriteFMulZ>; 311 defm : JWriteResFpuPair<WriteFMul64, [JFPU1, JFPM], 4, [1,2]>; 312 defm : JWriteResFpuPair<WriteFMul64X, [JFPU1, JFPM], 4, [1,2]>; 313 defm : JWriteResYMMPair<WriteFMul64Y, [JFPU1, JFPM], 4, [2,4], 2>; 314 defm : X86WriteResPairUnsupported<WriteFMul64Z>; 315 defm : X86WriteResPairUnsupported<WriteFMA>; 316 defm : X86WriteResPairUnsupported<WriteFMAX>; 317 defm : X86WriteResPairUnsupported<WriteFMAY>; 318 defm : X86WriteResPairUnsupported<WriteFMAZ>; 319 defm : JWriteResFpuPair<WriteDPPD, [JFPU1, JFPM, JFPA], 9, [1, 3, 3], 3>; 320 defm : JWriteResFpuPair<WriteDPPS, [JFPU1, JFPM, JFPA], 11, [1, 3, 3], 5>; 321 defm : JWriteResYMMPair<WriteDPPSY, [JFPU1, JFPM, JFPA], 12, [2, 6, 6], 10>; 322 defm : X86WriteResPairUnsupported<WriteDPPSZ>; 323 defm : JWriteResFpuPair<WriteFRcp, [JFPU1, JFPM], 2>; 324 defm : JWriteResFpuPair<WriteFRcpX, [JFPU1, JFPM], 2>; 325 defm : JWriteResYMMPair<WriteFRcpY, [JFPU1, JFPM], 2, [2,2], 2>; 326 defm : X86WriteResPairUnsupported<WriteFRcpZ>; 327 defm : JWriteResFpuPair<WriteFRsqrt, [JFPU1, JFPM], 2>; 328 defm : JWriteResFpuPair<WriteFRsqrtX, [JFPU1, JFPM], 2>; 329 defm : JWriteResYMMPair<WriteFRsqrtY, [JFPU1, JFPM], 2, [2,2], 2>; 330 defm : X86WriteResPairUnsupported<WriteFRsqrtZ>; 331 defm : JWriteResFpuPair<WriteFDiv, [JFPU1, JFPM], 19, [1, 19]>; 332 defm : JWriteResFpuPair<WriteFDivX, [JFPU1, JFPM], 19, [1, 19]>; 333 defm : JWriteResYMMPair<WriteFDivY, [JFPU1, JFPM], 38, [2, 38], 2>; 334 defm : X86WriteResPairUnsupported<WriteFDivZ>; 335 defm : JWriteResFpuPair<WriteFDiv64, [JFPU1, JFPM], 19, [1, 19]>; 336 defm : JWriteResFpuPair<WriteFDiv64X, [JFPU1, JFPM], 19, [1, 19]>; 337 defm : JWriteResYMMPair<WriteFDiv64Y, [JFPU1, JFPM], 38, [2, 38], 2>; 338 defm : X86WriteResPairUnsupported<WriteFDiv64Z>; 339 defm : JWriteResFpuPair<WriteFSqrt, [JFPU1, JFPM], 21, [1, 21]>; 340 defm : JWriteResFpuPair<WriteFSqrtX, [JFPU1, JFPM], 21, [1, 21]>; 341 defm : JWriteResYMMPair<WriteFSqrtY, [JFPU1, JFPM], 42, [2, 42], 2>; 342 defm : X86WriteResPairUnsupported<WriteFSqrtZ>; 343 defm : JWriteResFpuPair<WriteFSqrt64, [JFPU1, JFPM], 27, [1, 27]>; 344 defm : JWriteResFpuPair<WriteFSqrt64X, [JFPU1, JFPM], 27, [1, 27]>; 345 defm : JWriteResYMMPair<WriteFSqrt64Y, [JFPU1, JFPM], 54, [2, 54], 2>; 346 defm : X86WriteResPairUnsupported<WriteFSqrt64Z>; 347 defm : JWriteResFpuPair<WriteFSqrt80, [JFPU1, JFPM], 35, [1, 35]>; 348 defm : JWriteResFpuPair<WriteFSign, [JFPU1, JFPM], 2>; 349 defm : JWriteResFpuPair<WriteFRnd, [JFPU1, JSTC], 3>; 350 defm : JWriteResYMMPair<WriteFRndY, [JFPU1, JSTC], 3, [2,2], 2>; 351 defm : X86WriteResPairUnsupported<WriteFRndZ>; 352 defm : JWriteResFpuPair<WriteFLogic, [JFPU01, JFPX], 1>; 353 defm : JWriteResYMMPair<WriteFLogicY, [JFPU01, JFPX], 1, [2, 2], 2>; 354 defm : X86WriteResPairUnsupported<WriteFLogicZ>; 355 defm : JWriteResFpuPair<WriteFTest, [JFPU0, JFPA, JALU0], 3>; 356 defm : JWriteResYMMPair<WriteFTestY , [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>; 357 defm : X86WriteResPairUnsupported<WriteFTestZ>; 358 defm : JWriteResFpuPair<WriteFShuffle, [JFPU01, JFPX], 1>; 359 defm : JWriteResYMMPair<WriteFShuffleY, [JFPU01, JFPX], 1, [2, 2], 2>; 360 defm : X86WriteResPairUnsupported<WriteFShuffleZ>; 361 defm : JWriteResFpuPair<WriteFVarShuffle, [JFPU01, JFPX], 2, [1, 4], 3>; 362 defm : JWriteResYMMPair<WriteFVarShuffleY,[JFPU01, JFPX], 3, [2, 6], 6>; 363 defm : X86WriteResPairUnsupported<WriteFVarShuffleZ>; 364 defm : JWriteResFpuPair<WriteFBlend, [JFPU01, JFPX], 1>; 365 defm : JWriteResYMMPair<WriteFBlendY, [JFPU01, JFPX], 1, [2, 2], 2>; 366 defm : X86WriteResPairUnsupported<WriteFBlendZ>; 367 defm : JWriteResFpuPair<WriteFVarBlend, [JFPU01, JFPX], 2, [1, 4], 3>; 368 defm : JWriteResYMMPair<WriteFVarBlendY, [JFPU01, JFPX], 3, [2, 6], 6>; 369 defm : X86WriteResPairUnsupported<WriteFVarBlendZ>; 370 defm : JWriteResFpuPair<WriteFShuffle256, [JFPU01, JFPX], 1>; 371 defm : X86WriteResPairUnsupported<WriteFVarShuffle256>; 372 373 //////////////////////////////////////////////////////////////////////////////// 374 // Conversions. 375 //////////////////////////////////////////////////////////////////////////////// 376 377 defm : JWriteResFpuPair<WriteCvtSS2I, [JFPU1, JSTC, JFPA, JALU0], 7, [1,1,1,1], 2>; 378 defm : JWriteResFpuPair<WriteCvtPS2I, [JFPU1, JSTC], 3, [1,1], 1>; 379 defm : JWriteResYMMPair<WriteCvtPS2IY, [JFPU1, JSTC], 3, [2,2], 2>; 380 defm : X86WriteResPairUnsupported<WriteCvtPS2IZ>; 381 defm : JWriteResFpuPair<WriteCvtSD2I, [JFPU1, JSTC, JFPA, JALU0], 7, [1,1,1,1], 2>; 382 defm : JWriteResFpuPair<WriteCvtPD2I, [JFPU1, JSTC], 3, [1,1], 1>; 383 defm : JWriteResYMMPair<WriteCvtPD2IY, [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>; 384 defm : X86WriteResPairUnsupported<WriteCvtPD2IZ>; 385 386 // FIXME: f+3 ST, LD+STC latency 387 defm : JWriteResFpuPair<WriteCvtI2SS, [JFPU1, JSTC], 9, [1,1], 2>; 388 defm : JWriteResFpuPair<WriteCvtI2PS, [JFPU1, JSTC], 3, [1,1], 1>; 389 defm : JWriteResYMMPair<WriteCvtI2PSY, [JFPU1, JSTC], 3, [2,2], 2>; 390 defm : X86WriteResPairUnsupported<WriteCvtI2PSZ>; 391 defm : JWriteResFpuPair<WriteCvtI2SD, [JFPU1, JSTC], 9, [1,1], 2>; 392 defm : JWriteResFpuPair<WriteCvtI2PD, [JFPU1, JSTC], 3, [1,1], 1>; 393 defm : JWriteResYMMPair<WriteCvtI2PDY, [JFPU1, JSTC], 3, [2,2], 2>; 394 defm : X86WriteResPairUnsupported<WriteCvtI2PDZ>; 395 396 defm : JWriteResFpuPair<WriteCvtSS2SD, [JFPU1, JSTC], 7, [1,2], 2>; 397 defm : JWriteResFpuPair<WriteCvtPS2PD, [JFPU1, JSTC], 2, [1,1], 1>; 398 defm : JWriteResYMMPair<WriteCvtPS2PDY, [JFPU1, JSTC], 2, [2,2], 2>; 399 defm : X86WriteResPairUnsupported<WriteCvtPS2PDZ>; 400 401 defm : JWriteResFpuPair<WriteCvtSD2SS, [JFPU1, JSTC], 7, [1,2], 2>; 402 defm : JWriteResFpuPair<WriteCvtPD2PS, [JFPU1, JSTC], 3, [1,1], 1>; 403 defm : JWriteResYMMPair<WriteCvtPD2PSY, [JFPU1, JSTC, JFPX], 6, [2,2,4], 3>; 404 defm : X86WriteResPairUnsupported<WriteCvtPD2PSZ>; 405 406 defm : JWriteResFpuPair<WriteCvtPH2PS, [JFPU1, JSTC], 3, [1,1], 1>; 407 defm : JWriteResYMMPair<WriteCvtPH2PSY, [JFPU1, JSTC], 3, [2,2], 2>; 408 defm : X86WriteResPairUnsupported<WriteCvtPH2PSZ>; 409 410 defm : X86WriteRes<WriteCvtPS2PH, [JFPU1, JSTC], 3, [1,1], 1>; 411 defm : X86WriteRes<WriteCvtPS2PHY, [JFPU1, JSTC, JFPX], 6, [2,2,2], 3>; 412 defm : X86WriteResUnsupported<WriteCvtPS2PHZ>; 413 defm : X86WriteRes<WriteCvtPS2PHSt, [JFPU1, JSTC, JSAGU], 4, [1,1,1], 1>; 414 defm : X86WriteRes<WriteCvtPS2PHYSt, [JFPU1, JSTC, JFPX, JSAGU], 7, [2,2,2,1], 3>; 415 defm : X86WriteResUnsupported<WriteCvtPS2PHZSt>; 416 417 //////////////////////////////////////////////////////////////////////////////// 418 // Vector integer operations. 419 //////////////////////////////////////////////////////////////////////////////// 420 421 defm : X86WriteRes<WriteVecLoad, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>; 422 defm : X86WriteRes<WriteVecLoadX, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>; 423 defm : X86WriteRes<WriteVecLoadY, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>; 424 defm : X86WriteRes<WriteVecLoadNT, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>; 425 defm : X86WriteRes<WriteVecLoadNTY, [JLAGU, JFPU01, JVALU], 5, [1, 1, 1], 1>; 426 defm : X86WriteRes<WriteVecMaskedLoad, [JLAGU, JFPU01, JVALU], 6, [1, 1, 2], 1>; 427 defm : X86WriteRes<WriteVecMaskedLoadY, [JLAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>; 428 429 defm : X86WriteRes<WriteVecStore, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>; 430 defm : X86WriteRes<WriteVecStoreX, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>; 431 defm : X86WriteRes<WriteVecStoreY, [JSAGU, JFPU1, JSTC], 1, [1, 1, 1], 1>; 432 defm : X86WriteRes<WriteVecStoreNT, [JSAGU, JFPU1, JSTC], 2, [1, 1, 1], 1>; 433 defm : X86WriteRes<WriteVecStoreNTY, [JSAGU, JFPU1, JSTC], 2, [2, 2, 2], 1>; 434 defm : X86WriteRes<WriteVecMaskedStore, [JSAGU, JFPU01, JVALU], 6, [1, 1, 4], 1>; 435 defm : X86WriteRes<WriteVecMaskedStoreY, [JSAGU, JFPU01, JVALU], 6, [2, 2, 4], 2>; 436 437 defm : X86WriteRes<WriteVecMove, [JFPU01, JVALU], 1, [1, 1], 1>; 438 defm : X86WriteRes<WriteVecMoveX, [JFPU01, JVALU], 1, [1, 1], 1>; 439 defm : X86WriteRes<WriteVecMoveY, [JFPU01, JVALU], 1, [2, 2], 2>; 440 defm : X86WriteRes<WriteVecMoveToGpr, [JFPU0, JFPA, JALU0], 4, [1, 1, 1], 1>; 441 defm : X86WriteRes<WriteVecMoveFromGpr, [JFPU01, JFPX], 8, [1, 1], 2>; 442 443 defm : JWriteResFpuPair<WriteVecALU, [JFPU01, JVALU], 1>; 444 defm : JWriteResFpuPair<WriteVecALUX, [JFPU01, JVALU], 1>; 445 defm : X86WriteResPairUnsupported<WriteVecALUY>; 446 defm : X86WriteResPairUnsupported<WriteVecALUZ>; 447 defm : JWriteResFpuPair<WriteVecShift, [JFPU01, JVALU], 1>; 448 defm : JWriteResFpuPair<WriteVecShiftX, [JFPU01, JVALU], 1>; 449 defm : X86WriteResPairUnsupported<WriteVecShiftY>; 450 defm : X86WriteResPairUnsupported<WriteVecShiftZ>; 451 defm : JWriteResFpuPair<WriteVecShiftImm, [JFPU01, JVALU], 1>; 452 defm : JWriteResFpuPair<WriteVecShiftImmX,[JFPU01, JVALU], 1>; 453 defm : X86WriteResPairUnsupported<WriteVecShiftImmY>; 454 defm : X86WriteResPairUnsupported<WriteVecShiftImmZ>; 455 defm : X86WriteResPairUnsupported<WriteVarVecShift>; 456 defm : X86WriteResPairUnsupported<WriteVarVecShiftY>; 457 defm : X86WriteResPairUnsupported<WriteVarVecShiftZ>; 458 defm : JWriteResFpuPair<WriteVecIMul, [JFPU0, JVIMUL], 2>; 459 defm : JWriteResFpuPair<WriteVecIMulX, [JFPU0, JVIMUL], 2>; 460 defm : X86WriteResPairUnsupported<WriteVecIMulY>; 461 defm : X86WriteResPairUnsupported<WriteVecIMulZ>; 462 defm : JWriteResFpuPair<WritePMULLD, [JFPU0, JFPU01, JVIMUL, JVALU], 4, [2, 1, 2, 1], 3>; 463 defm : X86WriteResPairUnsupported<WritePMULLDY>; 464 defm : X86WriteResPairUnsupported<WritePMULLDZ>; 465 defm : JWriteResFpuPair<WriteMPSAD, [JFPU0, JVIMUL], 3, [1, 2]>; 466 defm : X86WriteResPairUnsupported<WriteMPSADY>; 467 defm : X86WriteResPairUnsupported<WriteMPSADZ>; 468 defm : JWriteResFpuPair<WritePSADBW, [JFPU01, JVALU], 2>; 469 defm : JWriteResFpuPair<WritePSADBWX, [JFPU01, JVALU], 2>; 470 defm : X86WriteResPairUnsupported<WritePSADBWY>; 471 defm : X86WriteResPairUnsupported<WritePSADBWZ>; 472 defm : JWriteResFpuPair<WritePHMINPOS, [JFPU0, JVALU], 2>; 473 defm : JWriteResFpuPair<WriteShuffle, [JFPU01, JVALU], 1>; 474 defm : JWriteResFpuPair<WriteShuffleX, [JFPU01, JVALU], 1>; 475 defm : X86WriteResPairUnsupported<WriteShuffleY>; 476 defm : X86WriteResPairUnsupported<WriteShuffleZ>; 477 defm : JWriteResFpuPair<WriteVarShuffle, [JFPU01, JVALU], 2, [1, 4], 3>; 478 defm : JWriteResFpuPair<WriteVarShuffleX, [JFPU01, JVALU], 2, [1, 4], 3>; 479 defm : X86WriteResPairUnsupported<WriteVarShuffleY>; 480 defm : X86WriteResPairUnsupported<WriteVarShuffleZ>; 481 defm : JWriteResFpuPair<WriteBlend, [JFPU01, JVALU], 1>; 482 defm : X86WriteResPairUnsupported<WriteBlendY>; 483 defm : X86WriteResPairUnsupported<WriteBlendZ>; 484 defm : JWriteResFpuPair<WriteVarBlend, [JFPU01, JVALU], 2, [1, 4], 3>; 485 defm : X86WriteResPairUnsupported<WriteVarBlendY>; 486 defm : X86WriteResPairUnsupported<WriteVarBlendZ>; 487 defm : JWriteResFpuPair<WriteVecLogic, [JFPU01, JVALU], 1>; 488 defm : JWriteResFpuPair<WriteVecLogicX, [JFPU01, JVALU], 1>; 489 defm : X86WriteResPairUnsupported<WriteVecLogicY>; 490 defm : X86WriteResPairUnsupported<WriteVecLogicZ>; 491 defm : JWriteResFpuPair<WriteVecTest, [JFPU0, JFPA, JALU0], 3>; 492 defm : JWriteResYMMPair<WriteVecTestY, [JFPU01, JFPX, JFPA, JALU0], 4, [2, 2, 2, 1], 3>; 493 defm : X86WriteResPairUnsupported<WriteVecTestZ>; 494 defm : X86WriteResPairUnsupported<WriteShuffle256>; 495 defm : X86WriteResPairUnsupported<WriteVarShuffle256>; 496 497 //////////////////////////////////////////////////////////////////////////////// 498 // Vector insert/extract operations. 499 //////////////////////////////////////////////////////////////////////////////// 500 501 defm : X86WriteRes<WriteVecInsert, [JFPU01, JVALU], 7, [1,1], 2>; 502 defm : X86WriteRes<WriteVecInsertLd, [JFPU01, JVALU, JLAGU], 4, [1,1,1], 1>; 503 defm : X86WriteRes<WriteVecExtract, [JFPU0, JFPA, JALU0], 3, [1,1,1], 1>; 504 defm : X86WriteRes<WriteVecExtractSt, [JFPU1, JSTC, JSAGU], 3, [1,1,1], 1>; 505 506 //////////////////////////////////////////////////////////////////////////////// 507 // SSE42 String instructions. 508 //////////////////////////////////////////////////////////////////////////////// 509 510 defm : JWriteResFpuPair<WritePCmpIStrI, [JFPU1, JVALU1, JFPA, JALU0], 7, [1, 2, 1, 1], 3>; 511 defm : JWriteResFpuPair<WritePCmpIStrM, [JFPU1, JVALU1, JFPA, JALU0], 8, [1, 2, 1, 1], 3>; 512 defm : JWriteResFpuPair<WritePCmpEStrI, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>; 513 defm : JWriteResFpuPair<WritePCmpEStrM, [JFPU1, JSAGU, JLAGU, JVALU, JVALU1, JFPA, JALU0], 14, [1, 2, 2, 6, 4, 1, 1], 9>; 514 515 //////////////////////////////////////////////////////////////////////////////// 516 // MOVMSK Instructions. 517 //////////////////////////////////////////////////////////////////////////////// 518 519 def : WriteRes<WriteFMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; } 520 def : WriteRes<WriteVecMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; } 521 defm : X86WriteResUnsupported<WriteVecMOVMSKY>; 522 def : WriteRes<WriteMMXMOVMSK, [JFPU0, JFPA, JALU0]> { let Latency = 3; } 523 524 //////////////////////////////////////////////////////////////////////////////// 525 // AES Instructions. 526 //////////////////////////////////////////////////////////////////////////////// 527 528 defm : JWriteResFpuPair<WriteAESIMC, [JFPU0, JVIMUL], 2>; 529 defm : JWriteResFpuPair<WriteAESKeyGen, [JFPU0, JVIMUL], 2>; 530 defm : JWriteResFpuPair<WriteAESDecEnc, [JFPU0, JVIMUL], 3, [1, 1], 2>; 531 532 //////////////////////////////////////////////////////////////////////////////// 533 // Horizontal add/sub instructions. 534 //////////////////////////////////////////////////////////////////////////////// 535 536 defm : JWriteResFpuPair<WriteFHAdd, [JFPU0, JFPA], 3>; 537 defm : JWriteResYMMPair<WriteFHAddY, [JFPU0, JFPA], 3, [2,2], 2>; 538 defm : JWriteResFpuPair<WritePHAdd, [JFPU01, JVALU], 1>; 539 defm : JWriteResFpuPair<WritePHAddX, [JFPU01, JVALU], 1>; 540 defm : X86WriteResPairUnsupported<WritePHAddY>; 541 542 //////////////////////////////////////////////////////////////////////////////// 543 // Carry-less multiplication instructions. 544 //////////////////////////////////////////////////////////////////////////////// 545 546 defm : JWriteResFpuPair<WriteCLMul, [JFPU0, JVIMUL], 2>; 547 548 //////////////////////////////////////////////////////////////////////////////// 549 // SSE4A instructions. 550 //////////////////////////////////////////////////////////////////////////////// 551 552 def JWriteINSERTQ: SchedWriteRes<[JFPU01, JVALU]> { 553 let Latency = 2; 554 let ResourceCycles = [1, 4]; 555 } 556 def : InstRW<[JWriteINSERTQ], (instrs INSERTQ, INSERTQI)>; 557 558 //////////////////////////////////////////////////////////////////////////////// 559 // AVX instructions. 560 //////////////////////////////////////////////////////////////////////////////// 561 562 def JWriteVBROADCASTYLd: SchedWriteRes<[JLAGU, JFPU01, JFPX]> { 563 let Latency = 6; 564 let ResourceCycles = [1, 2, 4]; 565 let NumMicroOps = 2; 566 } 567 def : InstRW<[JWriteVBROADCASTYLd, ReadAfterLd], (instrs VBROADCASTSDYrm, 568 VBROADCASTSSYrm)>; 569 570 def JWriteJVZEROALL: SchedWriteRes<[]> { 571 let Latency = 90; 572 let NumMicroOps = 73; 573 } 574 def : InstRW<[JWriteJVZEROALL], (instrs VZEROALL)>; 575 576 def JWriteJVZEROUPPER: SchedWriteRes<[]> { 577 let Latency = 46; 578 let NumMicroOps = 37; 579 } 580 def : InstRW<[JWriteJVZEROUPPER], (instrs VZEROUPPER)>; 581 582 /////////////////////////////////////////////////////////////////////////////// 583 // SchedWriteVariant definitions. 584 /////////////////////////////////////////////////////////////////////////////// 585 586 def JWriteZeroLatency : SchedWriteRes<[]> { 587 let Latency = 0; 588 } 589 590 // Certain instructions that use the same register for both source 591 // operands do not have a real dependency on the previous contents of the 592 // register, and thus, do not have to wait before completing. They can be 593 // optimized out at register renaming stage. 594 // Reference: Section 10.8 of the "Software Optimization Guide for AMD Family 595 // 15h Processors". 596 // Reference: Agner's Fog "The microarchitecture of Intel, AMD and VIA CPUs", 597 // Section 21.8 [Dependency-breaking instructions]. 598 599 def JWriteZeroIdiom : SchedWriteVariant<[ 600 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>, 601 SchedVar<MCSchedPredicate<TruePred>, [WriteALU]> 602 ]>; 603 def : InstRW<[JWriteZeroIdiom], (instrs SUB32rr, SUB64rr, 604 XOR32rr, XOR64rr)>; 605 606 def JWriteFZeroIdiom : SchedWriteVariant<[ 607 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>, 608 SchedVar<MCSchedPredicate<TruePred>, [WriteFLogic]> 609 ]>; 610 def : InstRW<[JWriteFZeroIdiom], (instrs XORPSrr, VXORPSrr, XORPDrr, VXORPDrr, 611 ANDNPSrr, VANDNPSrr, 612 ANDNPDrr, VANDNPDrr)>; 613 614 def JWriteVZeroIdiomLogic : SchedWriteVariant<[ 615 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>, 616 SchedVar<MCSchedPredicate<TruePred>, [WriteVecLogic]> 617 ]>; 618 def : InstRW<[JWriteVZeroIdiomLogic], (instrs MMX_PXORirr, MMX_PANDNirr)>; 619 620 def JWriteVZeroIdiomLogicX : SchedWriteVariant<[ 621 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>, 622 SchedVar<MCSchedPredicate<TruePred>, [WriteVecLogicX]> 623 ]>; 624 def : InstRW<[JWriteVZeroIdiomLogicX], (instrs PXORrr, VPXORrr, 625 PANDNrr, VPANDNrr)>; 626 627 def JWriteVZeroIdiomALU : SchedWriteVariant<[ 628 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>, 629 SchedVar<MCSchedPredicate<TruePred>, [WriteVecALU]> 630 ]>; 631 def : InstRW<[JWriteVZeroIdiomALU], (instrs MMX_PSUBBirr, MMX_PSUBDirr, 632 MMX_PSUBQirr, MMX_PSUBWirr, 633 MMX_PCMPGTBirr, MMX_PCMPGTDirr, 634 MMX_PCMPGTWirr)>; 635 636 def JWriteVZeroIdiomALUX : SchedWriteVariant<[ 637 SchedVar<MCSchedPredicate<ZeroIdiomPredicate>, [JWriteZeroLatency]>, 638 SchedVar<MCSchedPredicate<TruePred>, [WriteVecALUX]> 639 ]>; 640 def : InstRW<[JWriteVZeroIdiomALUX], (instrs PSUBBrr, VPSUBBrr, 641 PSUBDrr, VPSUBDrr, 642 PSUBQrr, VPSUBQrr, 643 PSUBWrr, VPSUBWrr, 644 PCMPGTBrr, VPCMPGTBrr, 645 PCMPGTDrr, VPCMPGTDrr, 646 PCMPGTQrr, VPCMPGTQrr, 647 PCMPGTWrr, VPCMPGTWrr)>; 648 649 // This write is used for slow LEA instructions. 650 def JWrite3OpsLEA : SchedWriteRes<[JALU1, JSAGU]> { 651 let Latency = 2; 652 } 653 654 // On Jaguar, a slow LEA is either a 3Ops LEA (base, index, offset), or an LEA 655 // with a `Scale` value different than 1. 656 def JSlowLEAPredicate : MCSchedPredicate< 657 CheckAny<[ 658 // A 3-operand LEA (base, index, offset). 659 IsThreeOperandsLEAFn, 660 // An LEA with a "Scale" different than 1. 661 CheckAll<[ 662 CheckIsImmOperand<2>, 663 CheckNot<CheckImmOperand<2, 1>> 664 ]> 665 ]> 666 >; 667 668 def JWriteLEA : SchedWriteVariant<[ 669 SchedVar<JSlowLEAPredicate, [JWrite3OpsLEA]>, 670 SchedVar<MCSchedPredicate<TruePred>, [WriteLEA]> 671 ]>; 672 673 def : InstRW<[JWriteLEA], (instrs LEA32r, LEA64r, LEA64_32r)>; 674 675 def JSlowLEA16r : SchedWriteRes<[JALU01]> { 676 let Latency = 3; 677 let ResourceCycles = [4]; 678 } 679 680 def : InstRW<[JSlowLEA16r], (instrs LEA16r)>; 681 682 } // SchedModel 683