Skip to content
artart78 edited this page Mar 26, 2013 · 1 revision

Table of Contents

General information

The PSP CPU is an "Allegrex", 32-bit R4000-based MIPS; it has all its instruction set, plus some special instructions by Sony.

Instructions

PSP's CPU has some instructions from MIPS IV: EXT, INS, WSBW, SEB, SEH, ROTR, ROT(R)V, BITREV, CLZ, CLO.
It doesn't seem to have:

  • 64bit instructions (of course)
  • LL, LDC1, LDC2, LWC2, SC, SDC1, SDC2, SWC2 (some of them are actually replaced by VFPU instructions, with different names)
  • T* (Trap and TLB) instructions
  • BLTZAL, BGEZAL, BLTZALL, BGEZALL
  • COP2 (VFPU) branching instructions
It also has its own instructions: MFIC and MTIC, and HALT.

Registers

User registers

The argument registers are: $a0..3 and $t0...3; arguments are then put at the bottom of the stack by the caller. Their content after calling a subroutine is unknown.
The registers $s0...7 and $fp are standard registers; they're saved on the stack by the caller, so their content is preserved when calling a subroutine.
The registers $t4...9 aren't saved either.
The registers $v0 and $v1 contain the return value of a function; $v0 contain its lower 32-bits and $v1, the higher 32-bits, if the function returns a 64-bit value. These aren't saved either.
The register $sp is still the stack pointer.

Kernel registers

The kernel register $gp isn't used a lot; its use is very specific (interruptman, pops, etc.).
$k1 is used to check permissions: each time an user function is called, it shifts $k1 left by 11 bits. The function is in user mode if the $k1 value has then its first (highest value) bit set. In then checks either if a pointer has its higher bit set, and/or if its end has its higher bit set, and/or if its size has its higher bit set. If one of those bits is set and we're in user mode, the function returns an error (if it checked the pointer/buffer, which is not always the case).
$at is used as a temporary register, for hardware manipulation sometimes (to store the hardware register address when reading/writing from/to it.
$k0 is a very special register, used in special places like exceptionman, interruptman, pops, etc.

Special instructions details

HALT: opcode 0x70000000. This instructions waits for an interruption to wake it up.
MFIC: opcode 0x70000024 with mask 0xFFFF07FF. It retrieves the interrupt controller state (1: interruptions enabled, 0: interruptions disabled) into the register described by mask 0x0000F800.
MTIC: opcode 0x70000026 with mask 0xFFFF07FF. It sets the interrupt controller state to the value which is in the register described by mask 0x0000F800.

Clone this wiki locally