-- rdpmc_all(uint64_t[nfixed+ngeneral] *dst) -- -- Generate code to read performance monitoring counter values into dst. -- -- The generated code is specialized based on the number of fixed- and -- general-purpose performance counters that are available in -- hardware. These numbers are determined separately via the CPUID instruction. -- -- In practice on Sandy Bridge - Skylake CPUs the number of -- fixed-purpose registers is three and the number of general-purpose -- registers is either four (hyperthreads enabled) or eight -- (hyperthreads disabled). function rdpmc_multi (Dst, nfixed, ngeneral) local offset = 0 -- Read a PMC register value into the next slot of the destination buffer local function rdpmc (isfixed, index) local arg = (isfixed and 0x40000000 or 0) + index | mov ecx, arg | rdpmc | mov [edi+offset], eax | mov [edi+offset+4], edx offset = offset + 8 end for i = 0, nfixed-1 do rdpmc(true, i) end for i = 0, ngeneral-1 do rdpmc(false, i) end | ret end