Commit Graph

154 Commits

Author SHA1 Message Date
chss95cs@gmail.com
33a6cfc0a7 Add special cases to DOT_PRODUCT_3/4 that detect whether they're calculating lengthsquared
Add alternate path to DOT_PRODUCT_3/4 for use_fast_dot_product that skips all the status register stuff and just remaps inf to qnan
Add OPCODE_TO_SINGLE to replace the CONVERT_F32_F64 - CONVERT_F64_F32 sequence we used to emit with the idea that a backend could implement a more correct rounding behavior if possible on its arch
Remove some impossible sequences like MUL_HI_I8/I16, MUL_ADD_F32, DIV_V128. These instructions have no equivalent in PPC. Many other instructions are unused/dead code and should be removed to make the x64 backend a better reference for future ones
Add backend_flags to Instr. Basically, flags field that a backend can use for whatever it wants when generating code.
Add backend instr flag to x64 that tells it to not generate code for an instruction. this allows sequences to consume subsequent instructions
Generate actual x64 code for VSL instruction instead of using callnativesafe
Detect repeated COMPARE instructions w/ identical operands and reuse the results in FLAGS if so. this eliminates a ton of garbage compare/set instructions.
If a COMPARE instructions destination is stored to context with no intervening instruction and no additional uses besides the store, do setx [ctx address]
Detect prefetchw and use it in CACHE_CONTROL if prefetch for write is requested instead of doing prefetch to all cache levels
Fixed an accident in an earlier commit by me, VECTOR_DENORMFLUSH was not being emitted at all, so denormal inputs to MUL_ADD_V128 were not becoming zero and outputs from DOT_PRODUCT_X were not either. I believe this introduced a bug into RDR where a wagon wouldnt spawn? (https://discord.com/channels/308194948048486401/308207592482668545/1000443975817252874)
Compute fresx in double precision using RECIP_F64 and then round to single instead of doing (double)(1.0f / (float)value), matching original behavior better
Refactor some of ppc_emit_fpu, much of the InstrEmit function are identical except for whether they round to single or not
Added "tail emitters" to X64Emitter. These are callbacks that get invoked with their label and the X64Emitter after the epilog code. This allows us to move cold code out of the critical path and in the future place constant pools near functions
guest_to_host_thunk/host_to_guest_thunk now gets directly rel32 called, instead of doing a mov
Add X64BackendContext structure, represents data before the start of the PPCContext
Instead of doing branchless sequence, do a compare and jump to tail emitted code for address translation. This makes converting addresses a 3 uop affair in most cases.
Do qnan move for dot product in a tail emitter
Detect whether EFLAGS bits are independent variables for the current cpu (not really detecting it ehe, just checking if zen) and if so generate inc/dec for add/sub 1
Detect whether low 32 bits of membase are 0. If they are then we can use membasereg.cvt32() in place of immediate 0 in many places, particularly in stores
Detect LOAD MODIFY STORE pattern for context variables (currently only done for 64 bit ones) and turn them into modify [context ptr]. This is done for add, sub, and, or, xor, not, neg
Tail emit error handling for TRAP opcodes
Stub out unused trap opcodes like TRAP_TRUE_I32, TRAP_TRUE_I64, TRAP_TRUE_I16 (the call_true/return_true opcodes for these types are also probably unused)
Remove BackpropTruncations. It was poorly written and causes crashes on the game Viva pinata (https://discord.com/channels/308194948048486401/701111856600711208/1000249460451983420)
2022-07-23 12:10:07 -07:00
Radosław Gliński
3757580f45 Merge pull request #52 from chrisps/canary_experimental
Fix previous batch of CPU changes
2022-07-18 09:20:35 +02:00
Gliniak
6e1e62378f Merge branch 'master' of https://github.com/xenia-project/xenia into canary_experimental 2022-07-17 21:27:52 +02:00
chss95cs@gmail.com
3717167bbe Preload ThreeFloatMask in DOT_PRODUCT_3
Use shuffle_ps instead of broadcastss, broadcastss is slower on many intel and amd processors and encodes to the same number of bytes as shuffle_ps
Detect and optimize away PERMUTE with a zero src2 and src3 in constant_propagation_pass instead of in the x64 sequence
For constant PERMUTE, do the Xor/And prior to LoadConstantXmm instead of in the generated code
Simplified code for PERMUTE
Added simplification rule that detects (lzcnt(x) >> log2(bitsizeof_x)) == ( x == 0)
Added set_srcN(value, idx) which can be used to set the nth source of an instruction, which makes more sense than having three different functions that only differ by the field they touch
Added Value::VisitValueOperands for iterating all Value operands an instruction has.
Add BackpropTruncations code to simplification_pass
Changed the (void**) dereferences of raw_context that are done to grab thread_state to instead reference PPCContext and the thread_state field. Moved the thread_state field to the tail of PPCContext.
Moved membase to the tail of PPCContext, since now it is reloaded very infrequently.
Rearranged PPCContext so that the condition registers come first (most accesses to them cant get SSA'd), moved lr and ctr to after gp regs since they are not accessed as much as the main gpregs. This way the most frequently
accessed registers will be accessible via a rel8 displacement instead of rel32 (ideally, we would have only certain CRs at the start, but xenia does pointer arithmetic on CR0's offset to get CRn)
Use alignas(64) to ensure PPCContext's padding
Map PPCContext specially so that the low 32 bits of the context register is 0xE0000000, for the 4k page offset check. Also allocate the page before, so that backends can store their own information that is not relevant to the PPCContext on that page and
reference that data in the generated asm via 8-bit signed displ or 32-bit signed displ. Currently this page is not being utilized, but I plan on stashing some data critical to the x86 backend there
Changed many wrong avx instructions, they worked but they were not intended for the data they operated on, meaning they transferred domains and caused 1-2 cycle stall each time
Added SimdDomain checking/deduction to X64Emitter.
Used SimdDomain code to fix a lot of float/int domain stalls

Use the low 32 bits of the context register instead of constant 0xE0000000 in ComputeAddress
Special path for SELECT_V128 with result of comparison that will use a blend instruction instead of and/or
Many HIR optimizations added in simp pass
A bunch of other stuff running out of time to write this msg
2022-07-17 09:52:40 -07:00
Triang3l
34a952d789 [Base] Wrap strdup and strcasecmp in xe:: functions 2022-07-17 16:14:29 +03:00
chss95cs@gmail.com
6a612b4d34 remove useless tag field from hir::Value
pack local_slot and constant in hir::Value
Instead of loading membase at the start of every function, just load it in HostToGuestThunk
vzeroupper in GuestToHostThunk before calling host function, and in HostToGuestThunk after calling function to prevent AVX dirty state slowdowns. In the future, check if CPU implements AVX as 128x2 and skip if so (https://john-h-k.github.io/VexTransitionPenalties.html)
Remove useless save/restore of ctx pointer, nothing modifies it and it prevents cpus from doing cross-function memory renaming (https://www.agner.org/forum/viewtopic.php?t=41). Could not remove the space on stack because of alignment issues, instead turned it into GUEST_SCRATCH64 which is a temporary that sequences may use
Reorder OpcodeInfo so that name is at offset 0, remove name and add GetOpcodeName function (name is only used for debug code, we are seperating frequently accessed data and rarely accessed data)
Add VECTOR_DENORMFLUSH opcode for handling output to DOT_PRODUCT and other opcodes that implicitly force denormal inputs/outputs to zero, will eventually use for implementing NJM
Rewrite sequences for LOAD_VECTOR_SHL/SHR. The mask with 0xf in it was pointless as all InstrEmit_ functions that create the load shift instructions do that in HIR. The tables are only used for nonzero constant inputs now, which are probably pretty rare. Instead of doing a shift and lookup, a base value is used for both in the constant table and adding/subtracting of the input is done
Reuse result of LoadVectorShl/Shr in InstrEmit_stvlx_, InstrEmit_stvrx_. We were previously calculating it twice which was contributing to the final sequences' fatness. Use OPCODE_SELECT instead of the sequence of or, andnot, and that it was using for merging
Add the proper unconditional denormal input flushing behavior to vfmadd, add it also to vfmsub (making the assumption it has the same behavior)
Remove constant propagation for DOT_PRODUCT_3/4
DOT_PRODUCT_3/4 now returns a vector with all four elements set to the result. (what we were doing before, truncating to float32 and then splatting didnt make any sense)
Add much more correct versions of DOT_PRODUCT_3/4, matching the Xb360's  to 1 bit. Still needs work to be a perfect emulation.
Add constant folding for OPCODE_SELECT, OPCODE_INSERT, OPCODE_PERMUTE, OPCODE_SWIZZLE
Remove constant folding for DOT_PRODUCT
Removed the multibyte nop code I committed earlier, it doesnt help us much because nops are only used for debug stuff and its ugly and wouldnt survive in a pr to main
Check for AVX512BMI, use vpermb to shuffle if supported
2022-07-16 10:25:04 -07:00
chss95cs@gmail.com
327cc9eff5 drastically reduce size of final generated code for rlwinm by adding special paths for rotations of 0, masks that discard the rotated bits and using And w/ UINT_MAX instead of truncate/zero extend
Add special case to TYPE_INT64's EmitAnd for UINT_MAX mask. Do mov32 to 32 if detected to take advantage of implicit zero xt/reg renaming

Add helper function for skipping assignment defs in instr.
Add helper function for checking if an opcode is binary value type
Add several new optimizations to simplificationpass, plus weak NZM calculation code (better full evaluation of Z/NZ will be done later) .
 List of optimizations:
  If a value is anded with a bitmask that it was already masked against, reuse the old value (this cuts out most FPSCR update garbage, although it does cause a local variable to be allocated for the masked FPSCR and it still repeatedly stores the masked value to the context)
  If masking a value that was or'ed against another check whether our mask only considers bits from one value or another. if so, change the operand to the OR input that actually matters
  If the only usage of a rotate left's output is an AND against a mask that discards the bits that were rotated in change the opcode to SHIFT_LEFT
  If masking against all ones, become an assign.
  If XOR or OR against 0, become an assign (additional FPSCR codegen cleanup)
  If XOR against all ones, become a NOT
Adding a direct CPUID check to x64_emitter for lzcnt, the version of xbyak we are using is skipping checking for lzcnt on all non-intel cpus, meaning we are generating the much slower bitscan path for AMD cpus.
2022-06-25 09:58:13 -07:00
chss95cs@gmail.com
549ee28a93 ome guest function calls can now be resolved and embedded directly in
the emitted asm as rel32 calls. Disabled by default, enabled via
resolve_rel32_guest_calls
detect whether cpu has fast jrcxz, fast loop/loope/loopne
much more thorough LoadConstantXMM
New cvar elide_e0_check that allows the backend to assume accesses via
the SP or TLS register will not cross into 0xe0 range
Add x64 codegen for Vector shift uint8
If has fast jrcxz use for some traptrue/breaktrue instructions
Use phat nops
Add cvar use_fast_dot_product, which uses a four instruction sequence
for both dot product instructions which ought to be equivalent. disabled
by default.
2022-06-20 15:08:18 -07:00
Gliniak
0b183a3582 Merge branch 'chris_cpu_changes' of https://github.com/Gliniak/xenia.git into canary_experimental 2022-06-17 14:04:58 +02:00
chrisps
e4fd015886 Juicy optimization goodness 2022-06-17 14:03:24 +02:00
chrisps
3ad80810b5 Optimized CONVERT_I64_TO_F64 with neat overflow trick
Reduced instruction count from 11 to 8, eliminated a movq stall.
2022-06-17 11:10:48 +02:00
Gliniak
0f2a7105b9 [CPU] Added constant propagation pass for: OPCODE_AND_NOT 2022-03-11 08:54:01 +01:00
Joel Linn
00e7de9297 [CPU] Improve vrsqrtefp accuracy 2022-02-16 17:09:28 -06:00
Joel Linn
d64848245d [CPU] Improve vrefp accuracy 2022-02-16 17:09:28 -06:00
Wunkolo
37aa3d129c [x64] Explicitly handle AND_NOT dest == src1
This addresses a JIT-issue in the case that the `src1` and `dest`
register are both the same. This issue only happens in the "generic"
x86 path but not in the BMI1-accelerated path.

Thanks Rick for the extensive debugging help.

When `src1` and `dest` were the same, then the `addc` instruction at
`82099A08` in title `584108FF` might emit the following assembly:
```
.text:82099A08                 andc      r11, r10, r11
  |
  | Jitted
  |
  V
00000000A0011B15  mov         rbx,r10
00000000A0011B18  not         rbx
00000000A0011B1B  and         rbx,rbx
```

This was due to the src1 operand and the destination register being the
same, which used to call the "else" case in the x64 emitter when it
needs to be handled explicitly due to register aliasing/allocation.

Addresses issue #1945
2022-01-10 15:48:49 -06:00
Wunkolo
4303f6b200 [x64] Fix OPCODE_AND_NOT src1-constant case
Fix the the case where src1 is constant and src2 is non-constant causing
an assert due to trying to call `.constant()` on the src2 operand.
Interfaces with an issue Gliniak was encountering where title `4D53082D`
encounters an assert. Also includes a BMI1-acceleration in the 64-bit
case where a temporary register is needed(the `and` x86 instruction only
supports immediate constants up to 32-bits).
2022-01-06 13:00:58 -06:00
Wunkolo
24d4e1e0e5 [x64] Add BMI1-based acceleration for AndNot
In the case of having two register operands for `AndNot`, the `andn` instruction can be used when the host supports `BMI1`. `andn` only supports 32-bit and 64-bit operands, so some register up-casting is needed.
2022-01-04 16:16:49 -06:00
Wunkolo
0fdb855a11 [JIT, x64] Add and implement OPCODE_AND_NOT
Verified the x64 implementation using `xenia-cpu-ppc-tests`.
2022-01-04 16:16:49 -06:00
gibbed
326220309b [x64] Handle constant in LOG2_F32/F64/V128. 2020-11-27 05:34:08 -06:00
gibbed
a48bb71c2f Overhaul logging. 2020-04-07 16:09:41 -05:00
gibbed
aa28430786 [x64] NAN up vmsum3fp128/vmsum4fp128.
It seems vmsum3fp128/vmsum4fp128 need to output a NAN on overflow.

Do so. Probably inefficiently.
2020-02-24 18:13:07 -06:00
gibbed
a6e6f0f7bf Lint cleanup. 2020-02-22 13:29:07 -06:00
Joel Linn
922f1f220a [CPU] Implement mftb instruction natively.
When the cvars clock_no_scaling and clock_source_raw are set, tick counts will be directly calculated in the emitted code.
2019-12-01 17:11:58 -06:00
Dr. Chat
b3d509eb01 [x64] Swap to using anchor variables instead of dummy function calls 2018-11-23 18:02:04 -06:00
Dr. Chat
b57bb74965 [x64] Change the parameters to host_to_guest_thunk
Shuffle some code around in x64_backend.cc
Add GetNativeParam to avoid hardcoding parameters
2018-11-23 18:02:04 -06:00
Dr. Chat
b2f9d54e7e [x64] Factor out memory handling code 2018-11-23 18:02:03 -06:00
Dr. Chat
bb74114cab [x64] Factor out control code 2018-11-23 18:02:03 -06:00
Dr. Chat
c318009733 [x64] Factor out vector handling code 2018-11-23 18:02:03 -06:00
Dr. Chat
6861cce492 [x64] Factor out a lot of the opcode handling code 2018-11-23 18:02:02 -06:00
Dr. Chat
696c3cd439 [x64] Remove most of RegisterSequences 2018-11-23 18:02:02 -06:00
gibbed
4c53bc5c9a [x64] Fix Travis whining. 2018-11-23 12:03:09 -06:00
gibbed
996093e499 [x64] Support constant src1 for Int32 VECTOR_SHL_V128/VECTOR_SHR_V128. 2018-11-23 09:33:30 -06:00
Margen67
896ac4a682 Update documentation.
- Convert http to https, provide archive link when possible.
- Made CPU-JIT.png more readable on dark themes;
Added a white background so there isn't black text on a black
background.
2018-11-22 09:20:09 -06:00
gibbed
4436616e6d [x64] Use constant a bit earlier in VECTOR_SHL_V128. 2018-11-18 08:17:04 -06:00
gibbed
44f194be35 [x64] Fix constant access in VECTOR_SHL_V128. 2018-11-18 08:13:37 -06:00
Triang3l
dd19701dc4 [CPU] Unify constant operand checks in pack/unpack 2018-06-18 13:55:46 +03:00
Triang3l
c89cc6a229 [CPU] vupkd3d: NaN on negative overflow and tests 2018-06-11 21:34:13 +03:00
Triang3l
0378f532ab [CPU] Fix W in 2101010 vupkd3d and revert untested saturation 2018-06-11 17:22:15 +03:00
Triang3l
06fcdef968 [CPU] Bring back saturation in D3DCOLOR vpkd3d128 2018-05-31 16:17:27 +03:00
Triang3l
d61aff4389 [CPU] v(u)pkd3d128: Support UINT_2101010 and don't saturate D3DCOLOR
Fix broken mesh polygons in the Call of Duty series. Also remove saturation of D3DCOLOR when packing because values near 3 may be accepted, while unpacking D3DCOLOR gives values near 1.
2018-05-31 14:42:11 +03:00
DrChat
157c7780af [JIT] Add V128 ADD/SUB (fixes #1095) 2018-03-03 18:24:57 -06:00
DrChat
1c1fdb4ccd [JIT] Properly mask NaNs in vctsxs 2018-03-03 14:06:45 -06:00
DrChat
3a8f8f2ecb [JIT] Fix OPCODE_SELECT V128 with certain combinations of constants 2018-03-02 18:56:28 -06:00
DrChat
fd0d2185ef [JIT] Full support for vcfux 2018-03-02 15:11:29 -06:00
DrChat
b0b920c040 Linting. 2018-03-02 12:14:09 -06:00
DrChat
6c97dbaf81 [JIT] Simplify VECTOR_ADD/SUB i32 with saturate 2018-03-02 11:48:19 -06:00
DrChat
131fcd1320 [JIT] Kill a couple instructions in VECTOR_CONVERT_F2I 2018-03-02 11:41:04 -06:00
DrChat
0577b6c9be [JIT] Full vctuxs support 2018-03-01 23:49:44 -06:00
DrChat
6fd75cea91 [CPU] Handle constant multiply in fmadd/fmsub in constant propagation pass 2018-03-01 20:04:56 -06:00
DrChat
43f9cebb0c [JIT] Rewrite CNTLZ and remove one branch 2018-02-16 12:51:39 -06:00