mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-15 10:00:45 +02:00
x86's REP STOS instruction is a memset (with element size!) with the ability to choose a direction of execution. Additionally it has a feature where if it faults part-way through the copy, an application can catch the fault and continue afterwards to know how many bytes got copied. RCX is the counter which decrements for each element, and RDI is the memory pointer. On fault these will reflect the last location that was attempted to be written. FEX doesn't support this behaviour which makes our lives easier. Without supporting that feature, this turns in to a directional memset by element size. Let's remove all the multiple blocks and just emit a single IR operation to improve performance of the JIT. Our generated code here was terrible, the IR was terrible, multiblock is always slow with RA. Just a general overall improvement. With profiling pressure-vessel this change deletes the hottest block that appeared in the trace. This instruction is very commonly used for memsetting a region to zero so it should be quite fast. We can also optimize REP MOVS in the future with a Memcpy IR operation in a similar fashion. Additionally in the future these can be optimized to use ARM's new MOPS instructions since the most common case is memset by byte. Which is when we should expose the "Fast REP STOS" CPUID bit. Both setp/setm/sete and cpyfp/cpyfm/cpyfe match `REP STOS` and `REP MOVS` respectively.