Repository navigation
vCPU x87 Comparison Flag Capture
Lifecycle: Performance - Unproven · Type: Instruction-selection optimization
State: Source-backed; runtime value is not established.
Status: Source-validated code-generation candidate; not implemented or benchmarked.
Mechanism class: Host instruction-selection optimization — not a shortcut.
Reviewed source:
322986f4c5502b3fa887a9605ac8cd88e9b2c579Primary files:
tcg/i386/tcg-target.c.inc,target/i386/ops_fpu.h.
The proposal changes how the same host flags are captured after a native floating-point comparison. It does not bypass a general emulation route based on an assumption, retained state, or compatibility policy.
It is a focused backend micro-optimization and belongs in the broader Performance Optimization Catalog.
The x86 TCG backend emits the hard-FPU comparison operation approximately as:
comiss/comisd sourceA, sourceB
pushf
pop result_registerThe x87 comparison consumer then retains only three flags:
res &= 0x45; /* CF, PF, ZF */
res <<= 8; /* map into guest C0/C2/C3 status positions */Most of the captured host flags are discarded.
flowchart LR
A[COMISS/COMISD] --> B[PUSHF to stack]
B --> C[POP full flags into GPR]
C --> D[Mask 0x45]
D --> E[Shift into guest x87 status]
comisd xmmA, xmmB
lahf
movzx result, ah
and result, 0x45LAHF captures the low status flags containing CF, PF, and ZF, but forces use of AH/RAX and may create extra moves, partial-register dependencies, or allocator constraints.
SETB -> CF
SETP -> PF
SETE -> ZF
combine into 0x45 layout
This avoids stack traffic and AH but may require more instructions and temporaries.
The current route remains the reference. Modern cores may handle the pair efficiently enough that a replacement does not win after register-allocation effects.
Potentially removed work:
- store/load through the architectural stack pointer;
- full-flags capture when only three bits are needed;
- stack-engine or dependency cost around
PUSHF/POP; - code-size or scheduling constraints of the current pair.
Potentially added work:
- forced RAX/AH allocation;
- moves to/from the desired result register;
- partial-register merging concerns;
- several
SETccinstructions and bit assembly; - additional spills under register pressure.
This is why source instruction count alone cannot select the winner.
| Area | Role |
|---|---|
tcg/i386/tcg-target.c.inc::OP_f32_f64(com) |
Emits comparison and flags capture |
target/i386/ops_fpu.h::gen_fcom_*() |
Masks 0x45 and maps flags to guest x87 status |
| TCG register allocator | Determines RAX/result-register moves and spills |
| host capability setup | Determines whether LAHF is admitted in the active mode |
For ordered greater-than, less-than, equal, and unordered comparisons, the candidate must produce the same three-bit mapping as the reference:
| Relation | ZF | PF | CF | Guest result |
|---|---|---|---|---|
| greater | 0 | 0 | 0 | C3/C2/C0 = 000 |
| less | 0 | 0 | 1 | 001 |
| equal | 1 | 0 | 0 | 100 |
| unordered | 1 | 1 | 1 | 111 |
Also test:
- positive/negative zero;
- infinities;
- quiet and signaling NaNs where supported by the current hard-FPU contract;
- single and double precision;
- destination register aliases and high register pressure;
- surrounding code that uses RAX/AH;
- exception/status behavior retained by the current comparison route.
| Counter/measurement | Purpose |
|---|---|
| dynamic hard-FPU comparison count | Reachability |
| hot guest PCs/blocks | Concentration |
| current vs candidate code bytes | Code-size effect |
| spills/reloads and forced moves | Allocator cost |
| stack-memory operations | Work removed |
| host sample weight | Runtime cost |
| exact guest status mismatches | Correctness |
Create a small generated-code benchmark with the same allocator constraints as TCG. A standalone hand-written instruction loop may hide the RAX pressure that determines the actual result.
comparisons execute frequently
candidate captures 0x45 exactly
stack flag round-trip disappears
additional RAX/temporary spills remain lower than removed cost
fixed guest work improves repeatably
- Assuming fewer source instructions means faster generated code.
- Ignoring LAHF availability/capability handling in 64-bit mode.
- Forcing RAX and increasing spills in hot blocks.
- Creating partial-register stalls or extra zero-extension work.
- Mishandling unordered NaN comparisons.
- Measuring only a synthetic loop without TCG register pressure.
- Giving this micro-optimization priority over helper/conversion paths without dynamic evidence.
- Count dynamic hard-FPU comparisons and identify hot blocks.
- Generate current, LAHF, and SETcc variants under realistic register pressure.
- Compare exact guest status bits across ordered/unordered inputs.
- Inspect code size, moves, spills, and host samples.
- Run Release ABBA/BAAB on a workload with verified reachability.
- Retain the current PUSHF/POP route if the result is neutral or host-dependent.
- vCPU Shortcut Candidates
- Windows XMM Register Budget
- Helper-Aware x87 Cache Retention
- Performance Optimization Catalog
Primary reference: This subject page is the design and research reference for x87 Comparison Flag Capture. Pull requests are implementation/test history only.
Lifecycle: Performance - Unproven · Mechanism: Host instruction-selection experiment
Reviewed source:322986f4c5502b3fa887a9605ac8cd88e9b2c579· Acceptance class: intended exact or behavior-preserving for its admitted scope
Replace the current COMISD/COMISS plus PUSHF/POP full-flag capture with a smaller sequence that extracts only CF, PF and ZF if it is measurably better on the target host.
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 |
|---|---|
tcg/i386/tcg-target.c.inc |
floating comparison emission and flag capture |
target/i386/ops_fpu.h |
consumer mask 0x45 and guest x87 status mapping |
flowchart TD
N0["Host floating compare"]
N1["pushfq"]
N0 --> N1
N2["pop general register"]
N1 --> N2
N3["Mask CF/PF/ZF"]
N2 --> N3
N4["Map to guest x87 status"]
N3 --> N4
flowchart TD
N0["Host floating compare"]
N1["lahf or setcc sequence"]
N0 --> N1
N2["Extract only CF/PF/ZF"]
N1 --> N2
N3["Map to guest status"]
N2 --> N3
N4["Reference sequence when not profitable"]
N3 --> N4
The consumer only needs three condition bits, so round-tripping the complete flags register through the stack may be unnecessary. However, LAHF constrains RAX/AH and SETcc uses several instructions, so the alternative can lose through moves, spills or dependencies. This is a focused assembly benchmark, not a redesign.
- Stack push/pop of full flags if an alternative is cheaper
- Exact ordered/equal/unordered flag semantics
- Guest status mapping
- Register allocation constraints
- Reference emission
; Current shape
comisd xmm0, xmm1
pushfq
pop r10
and r10d, 0x45
; Candidate A
comisd xmm0, xmm1
lahf
movzx r10d, ah
and r10d, 0x45
; Candidate B uses SETB/SETP/SETE and combines bits.The sketch defines the intended boundary; it is not a complete patch and does not replace source review, ownership design, or focused tests.
- CF/PF/ZF match for ordered less/greater/equal and unordered NaN cases.
- No unwanted dependency on RAX/AH corrupts surrounding allocation.
- Stack pointer/unwind behavior remains valid in current route.
- Choose by measured generated code, not instruction count alone.
No persistent state. The backend selector may use host-feature/microarchitecture policy if evidence supports it. Register allocator constraints are part of the candidate cost.
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.
- Small isolated change
- Exact differential oracle
- May remove memory/stack traffic
- Easy microarchitecture comparison
- LAHF partial-register/RAX pressure
- SETcc sequence may be longer
- Modern CPUs may optimize PUSHF/POP adequately
- Likely small whole-workload effect
Counters must be cheap, subsystem-owned, and snapshotted outside the hot loop. Record at least:
- comparison_dynamic_count
- current_vs_candidate_uops/latency
- extra_moves/spills
- host_code_bytes
- x87_compare_samples
- whole-vCPU change
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.
- Ordered less/greater/equal
- Quiet/signaling NaNs as supported
- Signed zeros
- Register-pressure fixtures
- Disassembly/uop benchmark
- Weighted guest block frequency
- Release A/B if dynamic count is meaningful
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 only if exact status bits match and weighted generated-code/runtime evidence beats the existing sequence on supported hosts.
Reject if register pressure or uops are worse, dynamic frequency is low, or gains vanish outside a microbenchmark.
CPU-and-vCPU-Execution · Performance-Unproven · Debugging-Tools-and-Commands · vCPU-Shortcut-Candidates
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