Skip to content

Sparc: Feature Request: Expose Missing SPARC/SPARCV9 Control, Status, and NPC Registers in Public API #2338

@gnudles

Description

@gnudles

Abstract

When building system-level or high-fidelity user-space emulators for SPARC (both SPARC V8 32-bit and SPARC V9 64-bit), developers must handle Register Window management (Spill and Fill traps) and control flow modifications (like System Calls or Interrupt returns).

Currently, Unicorn does not expose critical state registers (NPC, CWP, CANSAVE, CANRESTORE, CLEANWIN, WIM, TBA, TBR) through the public uc_reg_read/uc_reg_write API. This forces downstream users to implement highly complex, fragile, and slow JIT code-injection routines just to modify or query basic CPU states.

We request exposing these registers natively in the uc_sparc_reg enumeration.

Technical Context & The Problem

  1. The PC and NPC Coupling Issue

In standard Unicorn SPARC register handling, writing to UC_SPARC_REG_PC forces the Next Program Counter (NPC) to be PC + 4.

Looking at the underlying register write implementation:

case UC_SPARC_REG_PC:
CHECK_REG_TYPE(uint32_t); // or uint64_t on V9
env->pc = *(uint32_t *)value;
env->npc = *(uint32_t *)value + 4;
*setpc = 1;
break;

This works fine for basic linear execution, but it completely breaks branch delay slot modeling and syscall return redirection. In SPARC, a system call return or trap return frequently requires manually setting a non-contiguous target pair:

PC = Current PC + 4

NPC = Current PC + 8

Without direct access to write to NPC, setting PC forces NPC = PC + 4. If the next instruction is a branch delay slot or target, this results in immediate control-flow corruption.

  1. Missing Register Window Trackers

During deep function call stacks, SPARC CPUs trigger Window Overflow (0x05 or 0x060-0x0BF) and Window Underflow (0x06 or 0x080-0x0DF) traps. Handling these traps require the emulator host to query or modify the register window state variables stored inside QEMU’s core environment:

SPARC V8: PSR (Processor State Register - partially exposed but lacks clean write updates for window bits) and WIM (Window Invalid Mask).

SPARC V9: CWP (Current Window Pointer), CANSAVE, CANRESTORE, and CLEANWIN.

Because downstream developers cannot read/write these variables directly through uc_reg_read/uc_reg_write, we are forced to execute extremely hacky "Privilege Escalation" loops inside our host code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions