Commit Graph
459 Commits
Author SHA1 Message Date
LC 4f2d2e646e Merge pull request #4542 from Sonicadvance1/fexcore_reconstructions_getting_saved_today
FEXCore/JIT: Switch over to new vl64pair for RIP reconstruction
2025-05-01 13:28:16 -04:00
Ryan Houdek fc052efb91 FEXCore: Fixes x87 reduced precision
With the change from #4538 I had accidentally broken x87 reduced
precision.

This is due to the fact that we accidentally lost ABI information about
interpreter fallbacks supporting `preserve_all` or not. So now instead
of having some ABI callbacks supporting it and some not, just force
usage of `preserve_all` if it is supported by the compiler entirely.

Fixes Steam when x87 reduced precision is enabled.
2025-04-30 17:37:10 -07:00
Ryan Houdek c5754145c5 FEXCore/JIT: Switch over to new vl64pair for RIP reconstruction
As said in the implementation of this struct commit message. This new
pair struct optimizes specific cases of small forward only increments
that can fit in to 8-bit space, and small forward or backward jump cases
that fit in to 16-bit space.

Some stats of this change:
- Steam: 5.88MB down to 4.34MB. 73.8% the space consumed
- Steamwebhelper: 15.8MB down to 13.24MB. 83.8% space consumed
- Sonic Mania: 3.6MB down to 2.58MB. 71.6% space consumed

As for absolute stats when compared to all code buffer size:
- Steam: 86MB of code buffer to 5.88MB -> 4.34MB of RIP reconstruction.
  - 6.8% -> 5% code buffer space used for RIP reconstruction
- Steamwebhelper: 285MB of code buffer to 17MB -> 14.26MB of RIP reconstruction.
  - 5.9% -> 4.9% code buffer space used for RIP reconstruction
- Sonic Mania: 48.53MB of code buffer to 3.55MB -> 2.53MB of RIP reconstruction.
  - 7.3% -> 5.2% code buffer space used for RIP reconstruction
2025-04-30 15:41:43 -07:00
Ryan Houdek 5b9354cc74 JIT: Move interpreter ABI handlers in to the dispatcher
Fixes #4535

A handful of improvements on this.
* Reduces codegen around interpreter fallbacks
* Keeps ABI handling code in common Dispatcher code
* Improves I$ hitrate by most of the heavy code staying in Dispatcher

This cuts the amount of codegen inside the JIT for most interpreter
fallbacks by 1/2 or 1/3, by only doing the minimal amount of work in the
code blocks and doing most things in the dispatcher. The cost of which
is an additional branch per operation.

This should bring marginal performance improvements, but it should also
basically fall within noise. The bigger thing to care about here is a
smaller amount of code being generated for x87 blocks.
2025-04-29 22:35:39 -07:00
Ryan Houdek e1d032b5a6 Merge pull request #4540 from pmatos/MProtectLastPage
mprotect last page of CodeBuffer
2025-04-27 11:07:14 -07:00
Paulo Matos 791502afef Protect last page of CodeBuffer
protects last page of codebuffer. This should cause a
SIGSEGV if we try to access it. Until now it was possible to go over
and access out of bounds.

In addition, there a couple of clang-tidy fixes which should be NFC.
2025-04-25 20:41:18 +02:00
Tony Wasserka e89a913b69 JIT: Make memory write visible to other threads reading the same location 2025-04-25 09:47:13 +02:00
Tony Wasserka 293d77d412 JIT: Make code patching during (un-/)linking thread-safe 2025-04-25 09:21:09 +02:00
Ryan Houdek 6beb4b0f8b Merge pull request #4533 from Sonicadvance1/align_tail_in_the_pale_moonlight
JIT: Align JITCodeTail to native alignment
2025-04-24 16:18:45 -07:00
Ryan Houdek 32764ddf81 JIT: Moves VPCMPESTRX handler to use vectors
I pushed this off from the previous changes that were converting things
to vector as less important. It has now become more important to keep
these in vector registers until beyond the ABI boundary.

This will reduce burden on our JIT backend and just changes where the
movement in to GPRs occurs. Necessary for #4535
2025-04-24 10:09:26 -07:00
Ryan Houdek 735f537846 JIT: Align JITCodeTail to native alignment
Removes UB
2025-04-24 08:40:43 -07:00
Ryan Houdek adcefe62cf InstcountCI: Changes how code size is calculated
Due to how jit block tail padding is working, there's no real good way
to determine the true "implementation size" of an instruction without
the backend being aware of wanting to investigate it.

Trying to inject another instruction, or another IR operation actually
subtly changes codegen in a way that gives invalid results. The only
real way to get around this is to inject a known token in to the
instruction stream as we `ExitFunction`.

So inject a `udf #0x420f`, and change the scanning behaviour to find the
first one and cut everything else off afterwards.

This already scoops out some code in some game blocks that were
accidentally landing ExitFunction code in the json.

This also has been tested to work with #4528 with its InstCountCI
specific changes reverted.

This means we don't need to play subtle padding tricks in the JIT to get
the information we want in InstcountCI.
2025-04-23 12:56:46 -07:00
Tony Wasserka 0fe28129a0 JIT: Fix warning about unused variable 2025-04-18 11:16:46 +02:00
Ryan Houdek 00f8181c3a OpcodeDispatcher: Fix CPUID being a instruction fence
It is common practice for games to use CPUID as an instruction barrier
for various reasons. Ensure that we respect this by adding support for
an instruction barrier.
2025-04-15 15:42:43 -07:00
Ryan Houdek 60565cc2ef OpcodeDispatcher: Implement support for self-synchronizing cycle counter
FEAT_ECV added a new synchronizing cycle counter instruction that
restrict speculation across the cycle counter access. Because it
restricts speculation, it effectively acts like an isb and load dsb.

Luckily for us, this actually matches behaviour for what rdtscp does, so
we can take advantage of it if the host supports FEAT_ECV.
2025-04-15 15:42:43 -07:00
Paulo Matos cb972e165b Fix cast in ValidateCode impl 2025-04-15 09:35:46 +02:00
Ryan Houdek 9b0bb29d78 IR: Implement support for sha256h{2,}
I keep carrying this patch around. Not yet wired up to the instruction
implementation yet, but I don't want to forget about it.
2025-04-01 17:53:48 -07:00
Alyssa Rosenzweig 1f08f8df0d IR: allow VUShrNI with bitshift=0
encodes to Xtn, we need this to narrow.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-03-31 16:03:18 -04:00
Alyssa Rosenzweig 0038a0b19c IR: plumb Vector_FToISized op
this exposes the frint* opcodes in a new ir op

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-03-31 16:03:18 -04:00
Ryan Houdek bd1d6820b7 Merge pull request #4438 from Sonicadvance1/static_analysis_wars
Static analysis warning fixes
2025-03-27 20:30:37 -07:00
Lioncache 4497ab8844 JIT: Simplify SVE 256 operation asserts
We can make these slightly less verbose.
2025-03-27 16:55:20 -04:00
Alyssa Rosenzweig 2cfc42bd6a Arm64Emitter: simplify and fix !preserve_all regs
stop doing weird special cases. just dump all the regs except what aapcs64 says
we don't have to.

this fixes saving x18 across thunks and things. so probably fixes things *cry*

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-03-27 10:07:27 -04:00
Ryan Houdek 003de2b659 JIT: static analysis warnings 2025-03-27 04:36:41 -07:00
Ryan Houdek ab9123a427 JIT: Fix typo in VSha256U1 2025-03-25 18:19:37 -07:00
Alyssa Rosenzweig f87edbe1cb JIT: eliminate a zext in bfi
Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2025-03-25 17:36:59 -04:00
Ryan Houdek 929b111648 Merge pull request #4405 from Sonicadvance1/static_analysis_again
Various: More static analysis warnings cleanup
2025-03-17 13:08:11 -07:00
Ryan Houdek 9f2f10a65f IR: Add new 128-bit vector move operation
This allows us to slightly optimize some x87 behaviour.
2025-03-12 22:21:28 -07:00
Ryan Houdek b0b41d00ee Various: More static analysis warnings cleanup
NFC
2025-03-12 17:27:41 -07:00
Ryan Houdek a37d6a3841 JIT: Optimize CAS
Hey kid, want to see a sick trick?

Finally optimal codegen for 64-bit cmpxchg.
2025-03-07 14:24:45 -08:00
Ryan Houdek 4b36d4f1ea JIT: Fixe scalar reciprocal when AFP is supported
Somehow I had completely missed this and recent reciprocal tests have
exposed it as a problem. When AFP is supported but not RPRES then we
were hitting this code path.

We were failing to insert in to the destination correctly, which because
the reciprocal is calculated using fdiv using a synthesized constant,
this would just zero the remaining portion of the register.
2025-03-06 18:21:26 -08:00
Ryan Houdek 07afdca58b V{Load,Store}VectorMasked: Small offset support with ASIMD 2025-03-05 12:25:33 -08:00
Ryan Houdek 93ed346fd2 JIT: Optimize SVE offset VL loadstores
This was only wired up for 256-bit SVE and wasn't ever hit for 128-bit
SVE. Ensure it works with 128-bit SVE, so mulvl needs to know when
128-bit is used. Then wire it up for vmaskmovps/pd. This saves one
instruction per operation.

Fixes #3791.
2025-03-05 12:01:50 -08:00
Ryan Houdek b7f58e68c5 Merge pull request #4363 from pmatos/ReciprocalsFix
Improve reciprocal estimate and tests
2025-03-01 00:58:45 -08:00
Paulo Matos b5241e0f60 Improve reciprocal estimate and tests
3DNow Reciprocal estimations did not have enough accuracy. Tests were enabled
to check for accurate values of reciprocals.

* where needed, reciprocal accuracy was increased.
* 3DNow sqrt reciprocal fixed for negative values.
* New helper VFCopySign IR op added.

Fixes #4319.
2025-02-27 15:07:14 +01:00
Ryan Houdek 95694b2017 JIT: Optimize packed float min/max if AFP is supported
If AFP.AH is supported then fmin/fmax behaves like the x86 min/max
instruction so we don't need to jump through any additional hoops.
Support this use case to save a few instructions when AFP is supported.
2025-02-24 14:53:18 -08:00
Ryan Houdek de6931b1f5 OpcodeDispatcher: Emulate SHA1RNDS4 with ARM sha extensions
```diff
     "sha1rnds4 xmm0, xmm1, 10b": {
-      "ExpectedInstructionCount": 55,
+      "ExpectedInstructionCount": 10,
```

So I spent a few hours glaring at this instruction. Then spent a few
more glaring in to the sunset and then found the optimization.
2025-02-22 04:57:58 -08:00
Ryan Houdek cdf6a16efc JIT: Implement ARM VSha1SU1 IR operation 2025-02-19 11:33:38 -08:00
Ryan Houdek bbcd4c168c JIT: Implement support for VSha256U1 operation 2025-02-18 18:03:31 -08:00
Ryan Houdek a32b892787 FEXCore/Profiler: Implement support for JIT float fallbacks
Based on #4291 and #4324. Ideally this gets merged at the same time so
we can have Mangohud be on version 2 before giving them an upstream
patch.

Performance-wise this change falls within noise of my x87 microbench.

This just lets us track the number of float fallbacks FEX does, letting
us detect things like x87 fallbacks and how frequent they are, so we can
detect if a game might be slow or stuttering because of these fallbacks.
2025-02-11 14:41:16 -08:00
Ryan Houdek 3160e0a430 FEXCore: Keep PCMPISTRI arguments in vectors longer
This reduces our codegen size and removes a few umov instructions.
Performance falls within noise but this small change will allow us to do
more vector optimizations in C code in the future.
2025-02-11 12:57:11 -08:00
Ryan Houdek 6abf5b90b7 FEXCore/JIT: Pass Softfloat arguments as vector registers
This is preparation work to allow passing the corestate to the x87 soft
float handlers directly for some profile stats.

Performance-wise, this change falls within noise because it basically
moves the GPR->Vector moves from the JIT in to C code, my microbench saw
the largest excursion of 5% but that's still within noise in the current
design of my bench.

A more tangible win from this change alone is less codegen on the JIT
side.
2025-02-10 12:53:25 -08:00
Ryan Houdek 0ccd38f593 JIT: Fixes offset for LRCPC2 LoadStoreMemTSO
This was in an assert statement which wouldn't give us the offset.
2025-02-10 10:38:39 -08:00
Ryan Houdek 3ef695cf70 JIT: Optimize memory stores with zero
Minor optimization but I've seen it around.
2025-02-09 22:50:12 -08:00
Ryan Houdek dcfbc2f20e FEXCore/JIT: Encode the JITRIPReconstructionEntries using variable length integer
When #2722 implemented this initially and #4271 switched over to signed
int16_t there was assumptions made that int16_t was a reasonable
trade-off in encoding size versus needing to deal with 8-bit values
being too small in some cases.

In the common case we are almost always encoding 8-bit values because
instructions are typically linear (and less than 15-bytes in size), but
16-bit was chosen because optimizing JIT and multiple instructions that
don't cause exceptions can add up to larger than 8-bit.

Instead of hardcoding 16-bit values, implement a variable length integer
class where ~96.8% of values are 8-bit encoded, and the remaining 3.19% are encoded using 16-bit.
Due to some constraints that #4271 put in place, we can basically
guarantee currently that branch targets are within 16-bit. The VL class
does support 32-bit and 64-bit as well so if we change behaviour then
nothing needs to change.

Some stats when running Sonic Mania with multiblock enabled.
Encoded integers: 3,504,907
Encoded 8-bit:    3,393,095 (96.8%)
Encoded 16-bit:     111,812 (3.19%)
Encoded 32/64-bit:        0

Encoded Size:       3,615,181 bytes (3.44MiB)
Fixed encoded size: 7,007,604 bytes (6.68MiB)

Definitely worth using and saves the headache of large RIP/PC offsets
causing problems.
2025-02-03 11:54:52 -08:00
Paulo Matos 44c65c35c8 Revert "Enable RA of SVE Predicate Registers"
This reverts commit fcbf0de05a.

The initial user of this code has been re-implemented in  b148cc6c.
This is not needed any longer so we're removing it.
2025-01-29 11:56:19 +01:00
Paulo Matos 0bccb1ece5 Ensure predicate cache is reset when control flow leaves block
Whenever the control float leaves the block, it might clobber the
predicate register so we reset the cache whenever that happens.

Fixes #4264
2025-01-27 20:12:43 +01:00
Tony Wasserka 403e8f8702 CodeEmitter: Unify SingleUseForwardLabel and ForwardLabel 2025-01-22 18:25:35 +01:00
Ryan Houdek 56c95e3b36 Merge pull request #4285 from neobrain/fix_ptso_offsets
Fix crashes in Paranoid TSO mode
2025-01-21 08:31:11 -08:00
Tony Wasserka da58e6a597 Fix warnings about unused variables 2025-01-21 12:07:33 +01:00
Tony Wasserka 26685143be Update code formatting for logging macros 2025-01-21 12:01:33 +01:00