Repository navigation
Hot Path vCPU Native SSE Arithmetic
Lifecycle: Performance - Unproven · Type: Host-ISA shortcut
State: Source-backed; runtime value is not established.
Status: Source-validated host-ISA shortcut candidate; not implemented or benchmarked.
Mechanism class: Direct host instruction emission that bypasses general SSE helpers.
Reviewed source:
322986f4c5502b3fa887a9605ac8cd88e9b2c579Primary files:
target/i386/tcg/emit.c.inc,target/i386/ops_sse.h,target/i386/tcg/ops_sse_header.h.inc,tcg/i386/tcg-target.c.inc.
The fork already emits many x87 operations through native hard-FPU TCG operations. That does not mean guest SSE floating-point arithmetic is native.
Current helper declarations cover packed and scalar:
- add;
- subtract;
- multiply;
- divide;
- minimum/maximum;
- square root;
- comparisons and conversions.
The corresponding implementations operate through xemu/QEMU floating-point helper machinery, generally per element. The proposal emits a small supported subset as host SSE instructions and bypasses the helper ABI and per-lane dispatch.
This is a real shortcut because the current helper remains the general reference route. It is only equivalent if the candidate reproduces the required guest numerical environment, result bits, status flags, and untouched lanes. Otherwise it must remain an explicitly approximate mode.
Do not begin with the complete SSE floating-point instruction family.
A useful first candidate is:
Host: x86-64 with required SSE instruction
Guest form: register-to-register
Operations: packed/scalar ADD, MUL and SUB
Guest exceptions: masked
Rounding/denormal policy: explicitly admitted and recorded
Memory operands: reference route initially
MIN/MAX, DIV, SQRT, conversions and comparisons: reference route initially
This isolates helper elimination from memory faults, complex NaN rules, conversion saturation, and comparison-status semantics.
flowchart TD
A[Guest SSE FP instruction] --> B[Decode source and destination]
B --> C[Build pointers to guest XMM storage]
C --> D[Emit helper call]
D --> E[Helper loads elements]
E --> F[SoftFloat/x86 FP operation per active lane]
F --> G[Update result and guest FP status]
G --> H[Return through helper ABI]
H --> I[Continue translated execution]
The helper route is broad and portable. It is the maintained fallback for unsupported operations, hosts, numerical modes, and any condition whose exact behavior is not yet proven.
The first stage should still load and store guest XMM state around each supported operation:
flowchart TD
A[Guest register-register ADD/MUL/SUB] --> B{Host and guest FP policy admitted?}
B -->|No| R[Current helper reference]
B -->|Yes| C[Load source/destination guest XMM values]
C --> D[Emit corresponding packed/scalar host SSE opcode]
D --> E[Preserve scalar untouched lanes]
E --> F[Capture/merge required guest status]
F --> G[Store guest destination]
Illustrative packed chain:
movups xmm0, [guest_xmm0]
movups xmm1, [guest_xmm1]
mulps xmm0, xmm1
movups [guest_xmm0], xmm0Only after the per-instruction experiment is understood should a second experiment retain guest SSE values across a short supported run:
flowchart LR
A[Load guest XMM values] --> B[Native MULPS]
B --> C[Native ADDPS]
C --> D{Unsupported op, observation or exit?}
D -->|No| B
D -->|Yes| E[Materialize guest XMM state]
That second stage changes register lifetime and exit handling; it must not be bundled into the first patch.
Potentially removed work includes:
- helper call setup and ABI transitions;
- pointer argument construction;
- per-lane helper dispatch;
- repeated guest XMM load/store inside helpers;
- helper-induced x87 cache flushes in mixed code;
- larger generated-call sequences;
- eventually, intermediate architectural XMM stores between supported operations.
The actual value depends on dynamic instruction mix. Count supported guest operations by hot block before implementing broad backend support.
“Both guest and host support SSE” is not a sufficient equivalence proof.
The candidate must account for:
| Area | Required question |
|---|---|
| Rounding | Does active host MXCSR match guest rounding mode? |
| Exception flags | How are host status bits merged into guest MXCSR? |
| Exception masks | Can the host instruction trap when the guest operation should remain masked? |
| Denormals | Do host DAZ/FTZ settings match guest behavior? |
| NaNs | Are payload, quieting and operand-selection rules compatible? |
| Signed zero | Do add/sub/mul edge cases match? |
| Scalar forms | Are upper destination lanes preserved exactly? |
| Aliasing | Is destination/source overlap handled identically? |
| Host contamination | Is surrounding C code's FP environment restored? |
Do not introduce FMA. Replacing guest multiply followed by add with a fused operation changes rounding and destroys attribution.
A development implementation may expose two dispositions:
- Equivalent candidate: admitted only when host control/status handling reproduces tested guest semantics.
- Approximate candidate: uses a documented fixed host FP policy and accepts bounded output differences.
The Wiki and evidence must never describe the second as exact merely because games appear to run.
x86 minimum/maximum instructions have non-obvious NaN, signed-zero, and operand-selection behavior. Direct emission may be correct, but it needs its own oracle.
These may have higher local cost, but also bring additional special-case and exception behavior. Add them after the basic framework is proven.
They update flags or convert with saturation/indefinite results. Keep them on the helper route until exact guest-status behavior is demonstrated.
A direct arithmetic opcode with a host memory operand must not bypass guest address translation, alignment faults, page faults, watchpoints, or MMIO. The initial route should use register-register guest forms only.
| File/area | Role |
|---|---|
target/i386/tcg/ops_sse_header.h.inc |
Confirms current helper families |
target/i386/ops_sse.h |
Current helper semantics and per-lane operations |
target/i386/tcg/emit.c.inc |
Decode and helper-selection seam |
tcg/i386/tcg-target.c.inc |
Host x86 opcode emission and register constraints |
Guest CPUX86State::xmm_regs
|
Architectural XMM storage |
Guest sse_status / MXCSR |
Numerical policy and exception status |
| Counter | Unit | Meaning |
|---|---|---|
sse_fp_add_exec, mul_exec, sub_exec
|
instructions | Dynamic candidate frequency |
native_sse_entries |
instructions | Direct route reached |
sse_helper_entries |
instructions | Reference route reached |
native_sse_reject_* |
instructions | Rejection by operation, operand, host, or FP policy |
helper_calls_avoided |
calls | Local transition removal |
guest_xmm_loads_stores_emitted |
operations | State traffic before/after |
fp_environment_switches |
operations | Control-state cost |
host_code_bytes_per_guest_op |
bytes | Expansion |
result_or_status_mismatches |
cases | Correctness oracle failures |
For each admitted instruction, test:
- packed and scalar forms;
- every destination/source alias pattern;
- normals, zeros, subnormals, infinities, and NaNs;
- all guest rounding modes;
- masked and unmasked exception configurations;
- DAZ/FTZ combinations supported by the guest model;
- upper-lane preservation for scalar operations;
- mixed native-candidate and helper-reference sequences;
- mixed x87 and SSE execution;
- interrupt, exception, snapshot, reset, and TB-exit boundaries.
Use exact result and guest-status comparisons for an equivalence claim. For an approximate mode, record the declared numerical differences and compatibility scope.
A source change is not enough. For hot blocks, capture:
guest PC and instruction
reference host disassembly
candidate host disassembly
helper calls
architectural loads/stores
FP control operations
block execution count
host sample weight
The direct route should visibly remove the helper and emit the intended host operation. A compiler inlining the helper differently than expected can change the hypothesis.
candidate operations execute frequently
SSE helper calls fall
host samples in helper/SoftFloat paths fall
code expansion and XMM memory traffic fall
vCPU time per fixed guest work improves
result/status oracle remains within declared contract
If helper calls fall but MXCSR setup, spills, or architectural XMM traffic becomes the new dominant cost, the next step is not automatically a larger instruction set. Measure the new path first.
- Assuming host SSE semantics automatically equal guest Pentium III semantics.
- Ignoring guest exception status because exceptions are masked.
- Leaking guest MXCSR policy into host C code.
- Mishandling scalar upper lanes.
- Directly using guest memory without MMU/fault handling.
- Combining register retention with helper elimination in one un-attributable patch.
- Adding FMA or other algebraic rewrites.
- Expanding to MIN/MAX/conversions before basic operations are proven.
- Reporting synthetic throughput without retail reachability.
- Count candidate operations dynamically by guest PC and workload.
- Implement direct emission for one operation and register-register form.
- Keep same-binary helper reference routing.
- Build exact result/status differential tests and broken-policy controls.
- Inspect optimized Release host disassembly with matching DWARF.
- Add operations one at a time: ADD, MUL, SUB.
- Measure local helper elimination and total vCPU progress.
- Run CPU-focused tests, PGR2, Morrowind, and applicable XISO coverage.
- Only then evaluate retaining values across short instruction runs.
- Keep unsupported operations and numerical modes on the helper route.
- vCPU Shortcut Candidates
- Native Reciprocal Estimates
- Helper-Aware x87 Cache Retention
- Floating-Point Control-State Retention
- Windows XMM Register Budget
Primary reference: This subject page is the design and research reference for Native SSE Arithmetic. Pull requests are implementation/test history only.
Lifecycle: Performance - Unproven · Mechanism: Host-ISA direct-emission shortcut
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579· Acceptance class: intended exact or behavior-preserving for its admitted scope
Emit a narrowly admitted subset of guest SSE floating-point arithmetic directly instead of per-lane helper execution, under an explicit host FP-environment contract.
This entry remains Unproven: the source path and opportunity are concrete, but no accepted xemu runtime result has established that the candidate improves representative workloads. The page defines what must be bypassed, what remains mandatory, and how the hypothesis can be rejected.
| File / function | Role |
|---|---|
target/i386/tcg/emit.c.inc |
SSE arithmetic translation/helper selection |
target/i386/ops_sse.h |
per-element floating-point helper semantics |
tcg/i386/tcg-target.c.inc |
host vector register and instruction emission |
flowchart TD
N0["Guest packed/scalar add/mul/sub"]
N1["Helper call"]
N0 --> N1
N2["Per-lane softfloat operation/status"]
N1 --> N2
N3["Return result"]
N2 --> N3
N4["Materialize guest XMM"]
N3 --> N4
flowchart TD
N0["Admit operation/FP policy"]
N1["Load guest XMM"]
N0 --> N1
N2["Emit native addps/mulps/subps or scalar form"]
N1 --> N2
N3["Merge required status"]
N2 --> N3
N4["Store guest XMM"]
N3 --> N4
N5["Fallback otherwise"]
N4 --> N5
Sharing an instruction name does not prove identical behavior. The first experiment should isolate helper elimination for register-register ADD/MUL/SUB with masked exceptions and defined rounding/denormal policy. Retaining XMM values across multiple guest instructions is a later separate optimization.
- Helper ABI transitions
- Per-lane dispatch
- Eventually some intermediate guest-register loads/stores
- Guest memory/fault handling
- Unsupported operations
- Status/exception policy
- MIN/MAX/conversion quirks
- Reference helper
; Desired first-stage generated shape
movups xmm0, [guest_xmm0]
movups xmm1, [guest_xmm1]
mulps xmm0, xmm1
movups [guest_xmm0], xmm0
; A later experiment may keep xmm0 live across several admitted ops.The sketch defines the intended boundary; it is not a complete patch and does not replace source review, ownership design, or focused tests.
- Rounding, exception masks/status, DAZ/FTZ, NaN, signed zero and scalar upper-lane behavior follow the declared contract.
- No FMA contraction is introduced.
- Unsupported or environment-mismatched cases use helpers.
- Host environment is restored on exit.
Initial codegen loads/stores guest register storage per instruction. A later register-resident region requires TCG allocator integration, call/exit materialization, and backend-specific register availability.
The maintained reference path remains the fallback whenever admission, capability, lifetime, or validation is uncertain. A fast result with an unproven dependency is not acceptable as an exact optimization.
- Can turn several helpers into a short native sequence
- High potential in vector-heavy guest code
- Instruction-level differential tests are possible
- Foundation for register-resident SSE regions
- Numerical/exception mismatches
- Host environment setup may reduce savings
- Win64 register pressure
- Backend portability
- Broader operation set has many edge semantics
Counters must be cheap, subsystem-owned, and snapshotted outside the hot loop. Record at least:
- supported_SSE_ops_executed
- helpers_avoided
- guest_XMM_loads/stores
- FP_environment_switches
- host_code_bytes
- spills/reloads
- vCPU samples
A local reduction is not enough. Evidence must connect route reachability and removed work to fixed guest progress, CPU/GPU time where applicable, and p95/p99 behavior.
- Exact bits/status for normal/special values
- Destination/source aliasing
- Scalar upper lanes
- Mixed x87/SSE
- Rounding and denormal modes
- Exceptions masked/unmasked
- Generated-code inspection
- Short chains and games
Correctness runs may use validation layers, detailed comparisons, and fault injection. Performance acceptance must use optimized Release builds with matching symbols and minimal instrumentation.
Promote instruction families incrementally when their contract is proven and weighted execution plus Release measurements justify direct emission.
Reject a blanket 'host supports SSE' implementation or any patch that silently changes FP policy, contracts operations, or leaves host state contaminated.
CPU-and-vCPU-Execution · Performance-Unproven · Hot-Path-vCPU-FP-Control-State-Retention · vCPU-Windows-XMM-Register-Budget
PR pages may be linked as supporting evidence, but they are not substitutes for this reference.
DSP tooling guide and navigation updated November 2, 2026 for experimental PR #384, source 8f51d237. Capture/replay usage and limits.
The earlier wiki-wide review was published November 1, 2026. Emulator source: b7140848. Reviewed wiki content: 1d2b671. Current status · Release availability · Publication process.
- Home
- Current status
- Stable versus main
- Implemented mechanisms
- Controls and defaults
- Measured results and limits
- Complete change register
- System
- CPU and vCPU
- Memory and DMA
- Graphics / NV2A
- APU and audio
- Timing and timers
- Platform and I/O
- Hardware observations
- Fidelity boundaries
- Methodology
- PGR2 routes
- Debugging lag / hot paths
- Tools and commands
- DSP capture, replay and fuzzing
- HLE readiness and public XISO proof
- Concurrent DSP shadow and OpenAL proof
- DSP HLE operation inventory
- DSP HLE fix examples and testing
- Development
- Upstream shortlist
- Wiki maintenance
- Research / retired work
- Optimization catalog
- Hot-path shortcuts
- Researched experiments
- Unproven proposal directory
- PR lessons
- September26 snapshot
Repository · PRs · Issues