mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-12 14:46:49 +01:00

Rather than introduce this handling in every system instruction that modifies the FPSCR directly, we can instead just handle it within the data structure instead, which avoids duplicating mask handling across instructions. This also allows handling proper masking from the debugger register windows themselves without duplicating masking behavior there either.
866 lines
15 KiB
C++
866 lines
15 KiB
C++
// Copyright 2008 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
// Gekko related unions, structs, ...
|
|
|
|
#pragma once
|
|
|
|
#include "Common/BitField.h"
|
|
#include "Common/CommonTypes.h"
|
|
|
|
// --- Gekko Instruction ---
|
|
|
|
union UGeckoInstruction
|
|
{
|
|
u32 hex = 0;
|
|
|
|
UGeckoInstruction() = default;
|
|
UGeckoInstruction(u32 hex_) : hex(hex_) {}
|
|
struct
|
|
{
|
|
// Record bit
|
|
// 1, if the condition register should be updated by this instruction
|
|
u32 Rc : 1;
|
|
u32 SUBOP10 : 10;
|
|
// Source GPR
|
|
u32 RB : 5;
|
|
// Source or destination GPR
|
|
u32 RA : 5;
|
|
// Destination GPR
|
|
u32 RD : 5;
|
|
// Primary opcode
|
|
u32 OPCD : 6;
|
|
};
|
|
struct
|
|
{
|
|
// Immediate, signed 16-bit
|
|
signed SIMM_16 : 16;
|
|
u32 : 5;
|
|
// Conditions on which to trap
|
|
u32 TO : 5;
|
|
u32 OPCD_2 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 Rc_2 : 1;
|
|
u32 : 10;
|
|
u32 : 5;
|
|
u32 : 5;
|
|
// Source GPR
|
|
u32 RS : 5;
|
|
u32 OPCD_3 : 6;
|
|
};
|
|
struct
|
|
{
|
|
// Immediate, unsigned 16-bit
|
|
u32 UIMM : 16;
|
|
u32 : 5;
|
|
u32 : 5;
|
|
u32 OPCD_4 : 6;
|
|
};
|
|
struct
|
|
{
|
|
// Link bit
|
|
// 1, if branch instructions should put the address of the next instruction into the link
|
|
// register
|
|
u32 LK : 1;
|
|
// Absolute address bit
|
|
// 1, if the immediate field represents an absolute address
|
|
u32 AA : 1;
|
|
// Immediate, signed 24-bit
|
|
u32 LI : 24;
|
|
u32 OPCD_5 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 LK_2 : 1;
|
|
u32 AA_2 : 1;
|
|
// Branch displacement, signed 14-bit (right-extended by 0b00)
|
|
u32 BD : 14;
|
|
// Branch condition
|
|
u32 BI : 5;
|
|
// Conditional branch control
|
|
u32 BO : 5;
|
|
u32 OPCD_6 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 LK_3 : 1;
|
|
u32 : 10;
|
|
u32 : 5;
|
|
u32 BI_2 : 5;
|
|
u32 BO_2 : 5;
|
|
u32 OPCD_7 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 : 11;
|
|
u32 RB_2 : 5;
|
|
u32 RA_2 : 5;
|
|
// ?
|
|
u32 L : 1;
|
|
u32 : 1;
|
|
// Destination field in CR or FPSCR
|
|
u32 CRFD : 3;
|
|
u32 OPCD_8 : 6;
|
|
};
|
|
struct
|
|
{
|
|
signed SIMM_16_2 : 16;
|
|
u32 RA_3 : 5;
|
|
u32 L_2 : 1;
|
|
u32 : 1;
|
|
u32 CRFD_2 : 3;
|
|
u32 OPCD_9 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 UIMM_2 : 16;
|
|
u32 RA_4 : 5;
|
|
u32 L_3 : 1;
|
|
u32 : 1;
|
|
u32 CRFD_3 : 3;
|
|
u32 OPCD_A : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 : 1;
|
|
u32 SUBOP10_2 : 10;
|
|
u32 RB_5 : 5;
|
|
u32 RA_5 : 5;
|
|
u32 L_4 : 1;
|
|
u32 : 1;
|
|
u32 CRFD_4 : 3;
|
|
u32 OPCD_B : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 : 16;
|
|
// Segment register
|
|
u32 SR : 4;
|
|
u32 : 1;
|
|
u32 RS_2 : 5;
|
|
u32 OPCD_C : 6;
|
|
};
|
|
|
|
// Table 59
|
|
struct
|
|
{
|
|
u32 Rc_4 : 1;
|
|
u32 SUBOP5 : 5;
|
|
// ?
|
|
u32 RC : 5;
|
|
u32 : 5;
|
|
u32 RA_6 : 5;
|
|
u32 RD_2 : 5;
|
|
u32 OPCD_D : 6;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u32 : 10;
|
|
// Overflow enable
|
|
u32 OE : 1;
|
|
// Special-purpose register
|
|
u32 SPR : 10;
|
|
u32 : 11;
|
|
};
|
|
struct
|
|
{
|
|
u32 : 10;
|
|
u32 OE_3 : 1;
|
|
// Upper special-purpose register
|
|
u32 SPRU : 5;
|
|
// Lower special-purpose register
|
|
u32 SPRL : 5;
|
|
u32 : 11;
|
|
};
|
|
|
|
// rlwinmx
|
|
struct
|
|
{
|
|
u32 Rc_3 : 1;
|
|
// Mask end
|
|
u32 ME : 5;
|
|
// Mask begin
|
|
u32 MB : 5;
|
|
// Shift amount
|
|
u32 SH : 5;
|
|
u32 : 16;
|
|
};
|
|
|
|
// crxor
|
|
struct
|
|
{
|
|
u32 : 11;
|
|
// Source bit in the CR
|
|
u32 CRBB : 5;
|
|
// Source bit in the CR
|
|
u32 CRBA : 5;
|
|
// Destination bit in the CR
|
|
u32 CRBD : 5;
|
|
u32 : 6;
|
|
};
|
|
|
|
// mftb
|
|
struct
|
|
{
|
|
u32 : 11;
|
|
// Time base register
|
|
u32 TBR : 10;
|
|
u32 : 11;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u32 : 11;
|
|
// Upper time base register
|
|
u32 TBRU : 5;
|
|
// Lower time base register
|
|
u32 TBRL : 5;
|
|
u32 : 11;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u32 : 18;
|
|
// Source field in the CR or FPSCR
|
|
u32 CRFS : 3;
|
|
u32 : 2;
|
|
u32 CRFD_5 : 3;
|
|
u32 : 6;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u32 : 12;
|
|
// Field mask, identifies the CR fields to be updated by mtcrf
|
|
u32 CRM : 8;
|
|
u32 : 1;
|
|
// Destination FPR
|
|
u32 FD : 5;
|
|
u32 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 : 6;
|
|
// Source FPR
|
|
u32 FC : 5;
|
|
// Source FPR
|
|
u32 FB : 5;
|
|
// Source FPR
|
|
u32 FA : 5;
|
|
// Source FPR
|
|
u32 FS : 5;
|
|
u32 : 6;
|
|
};
|
|
struct
|
|
{
|
|
u32 : 17;
|
|
// Field mask, identifies the FPSCR fields to be updated by mtfsf
|
|
u32 FM : 8;
|
|
u32 : 7;
|
|
};
|
|
|
|
// paired single quantized load/store
|
|
struct
|
|
{
|
|
u32 : 1;
|
|
u32 SUBOP6 : 6;
|
|
// Graphics quantization register to use
|
|
u32 Ix : 3;
|
|
// 0: paired single, 1: scalar
|
|
u32 Wx : 1;
|
|
u32 : 1;
|
|
// Graphics quantization register to use
|
|
u32 I : 3;
|
|
// 0: paired single, 1: scalar
|
|
u32 W : 1;
|
|
u32 : 16;
|
|
};
|
|
|
|
struct
|
|
{
|
|
signed SIMM_12 : 12;
|
|
u32 : 20;
|
|
};
|
|
|
|
struct
|
|
{
|
|
u32 : 11;
|
|
// Number of bytes to use in lswi/stswi (0 means 32 bytes)
|
|
u32 NB : 5;
|
|
};
|
|
};
|
|
|
|
//
|
|
// --- Gekko Special Registers ---
|
|
//
|
|
|
|
// quantize types
|
|
enum EQuantizeType : u32
|
|
{
|
|
QUANTIZE_FLOAT = 0,
|
|
QUANTIZE_INVALID1 = 1,
|
|
QUANTIZE_INVALID2 = 2,
|
|
QUANTIZE_INVALID3 = 3,
|
|
QUANTIZE_U8 = 4,
|
|
QUANTIZE_U16 = 5,
|
|
QUANTIZE_S8 = 6,
|
|
QUANTIZE_S16 = 7,
|
|
};
|
|
|
|
// GQR Register
|
|
union UGQR
|
|
{
|
|
BitField<0, 3, EQuantizeType> st_type;
|
|
BitField<8, 6, u32> st_scale;
|
|
BitField<16, 3, EQuantizeType> ld_type;
|
|
BitField<24, 6, u32> ld_scale;
|
|
|
|
u32 Hex = 0;
|
|
|
|
UGQR() = default;
|
|
explicit UGQR(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
#define XER_CA_SHIFT 29
|
|
#define XER_OV_SHIFT 30
|
|
#define XER_SO_SHIFT 31
|
|
#define XER_OV_MASK 1
|
|
#define XER_SO_MASK 2
|
|
// XER
|
|
union UReg_XER
|
|
{
|
|
struct
|
|
{
|
|
u32 BYTE_COUNT : 7;
|
|
u32 : 1;
|
|
u32 BYTE_CMP : 8;
|
|
u32 : 13;
|
|
u32 CA : 1;
|
|
u32 OV : 1;
|
|
u32 SO : 1;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_XER() = default;
|
|
explicit UReg_XER(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
// Machine State Register
|
|
union UReg_MSR
|
|
{
|
|
struct
|
|
{
|
|
u32 LE : 1;
|
|
u32 RI : 1;
|
|
u32 PM : 1;
|
|
u32 : 1; // res28
|
|
u32 DR : 1;
|
|
u32 IR : 1;
|
|
u32 IP : 1;
|
|
u32 : 1; // res24
|
|
u32 FE1 : 1;
|
|
u32 BE : 1;
|
|
u32 SE : 1;
|
|
u32 FE0 : 1;
|
|
u32 MCHECK : 1;
|
|
u32 FP : 1;
|
|
u32 PR : 1;
|
|
u32 EE : 1;
|
|
u32 ILE : 1;
|
|
u32 : 1; // res14
|
|
u32 POW : 1;
|
|
u32 res : 13;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_MSR() = default;
|
|
explicit UReg_MSR(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
#define FPRF_SHIFT 12
|
|
#define FPRF_MASK (0x1F << FPRF_SHIFT)
|
|
|
|
// FPSCR exception flags
|
|
enum FPSCRExceptionFlag : u32
|
|
{
|
|
FPSCR_FX = 1U << (31 - 0),
|
|
FPSCR_FEX = 1U << (31 - 1),
|
|
FPSCR_VX = 1U << (31 - 2),
|
|
FPSCR_OX = 1U << (31 - 3),
|
|
FPSCR_UX = 1U << (31 - 4),
|
|
FPSCR_ZX = 1U << (31 - 5),
|
|
FPSCR_XX = 1U << (31 - 6),
|
|
FPSCR_VXSNAN = 1U << (31 - 7),
|
|
FPSCR_VXISI = 1U << (31 - 8),
|
|
FPSCR_VXIDI = 1U << (31 - 9),
|
|
FPSCR_VXZDZ = 1U << (31 - 10),
|
|
FPSCR_VXIMZ = 1U << (31 - 11),
|
|
FPSCR_VXVC = 1U << (31 - 12),
|
|
FPSCR_VXSOFT = 1U << (31 - 21),
|
|
FPSCR_VXSQRT = 1U << (31 - 22),
|
|
FPSCR_VXCVI = 1U << (31 - 23),
|
|
FPSCR_VE = 1U << (31 - 24),
|
|
|
|
FPSCR_VX_ANY = FPSCR_VXSNAN | FPSCR_VXISI | FPSCR_VXIDI | FPSCR_VXZDZ | FPSCR_VXIMZ | FPSCR_VXVC |
|
|
FPSCR_VXSOFT | FPSCR_VXSQRT | FPSCR_VXCVI,
|
|
|
|
FPSCR_ANY_X = FPSCR_OX | FPSCR_UX | FPSCR_ZX | FPSCR_XX | FPSCR_VX_ANY,
|
|
};
|
|
|
|
// Floating Point Status and Control Register
|
|
union UReg_FPSCR
|
|
{
|
|
struct
|
|
{
|
|
// Rounding mode (towards: nearest, zero, +inf, -inf)
|
|
u32 RN : 2;
|
|
// Non-IEEE mode enable (aka flush-to-zero)
|
|
u32 NI : 1;
|
|
// Inexact exception enable
|
|
u32 XE : 1;
|
|
// IEEE division by zero exception enable
|
|
u32 ZE : 1;
|
|
// IEEE underflow exception enable
|
|
u32 UE : 1;
|
|
// IEEE overflow exception enable
|
|
u32 OE : 1;
|
|
// Invalid operation exception enable
|
|
u32 VE : 1;
|
|
// Invalid operation exception for integer conversion (sticky)
|
|
u32 VXCVI : 1;
|
|
// Invalid operation exception for square root (sticky)
|
|
u32 VXSQRT : 1;
|
|
// Invalid operation exception for software request (sticky)
|
|
u32 VXSOFT : 1;
|
|
// reserved
|
|
u32 : 1;
|
|
// Floating point result flags (includes FPCC) (not sticky)
|
|
// from more to less significand: class, <, >, =, ?
|
|
u32 FPRF : 5;
|
|
// Fraction inexact (not sticky)
|
|
u32 FI : 1;
|
|
// Fraction rounded (not sticky)
|
|
u32 FR : 1;
|
|
// Invalid operation exception for invalid comparison (sticky)
|
|
u32 VXVC : 1;
|
|
// Invalid operation exception for inf * 0 (sticky)
|
|
u32 VXIMZ : 1;
|
|
// Invalid operation exception for 0 / 0 (sticky)
|
|
u32 VXZDZ : 1;
|
|
// Invalid operation exception for inf / inf (sticky)
|
|
u32 VXIDI : 1;
|
|
// Invalid operation exception for inf - inf (sticky)
|
|
u32 VXISI : 1;
|
|
// Invalid operation exception for SNaN (sticky)
|
|
u32 VXSNAN : 1;
|
|
// Inexact exception (sticky)
|
|
u32 XX : 1;
|
|
// Division by zero exception (sticky)
|
|
u32 ZX : 1;
|
|
// Underflow exception (sticky)
|
|
u32 UX : 1;
|
|
// Overflow exception (sticky)
|
|
u32 OX : 1;
|
|
// Invalid operation exception summary (not sticky)
|
|
u32 VX : 1;
|
|
// Enabled exception summary (not sticky)
|
|
u32 FEX : 1;
|
|
// Exception summary (sticky)
|
|
u32 FX : 1;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
// The FPSCR's 20th bit (11th from a little endian perspective)
|
|
// is defined as reserved and set to zero. Attempts to modify it
|
|
// are ignored by hardware, so we do the same.
|
|
static constexpr u32 mask = 0xFFFFF7FF;
|
|
|
|
UReg_FPSCR() = default;
|
|
explicit UReg_FPSCR(u32 hex_) : Hex{hex_ & mask} {}
|
|
|
|
UReg_FPSCR& operator=(u32 value)
|
|
{
|
|
Hex = value & mask;
|
|
return *this;
|
|
}
|
|
|
|
UReg_FPSCR& operator|=(u32 value)
|
|
{
|
|
Hex |= value & mask;
|
|
return *this;
|
|
}
|
|
|
|
UReg_FPSCR& operator&=(u32 value)
|
|
{
|
|
Hex &= value;
|
|
return *this;
|
|
}
|
|
|
|
UReg_FPSCR& operator^=(u32 value)
|
|
{
|
|
Hex ^= value & mask;
|
|
return *this;
|
|
}
|
|
|
|
void ClearFIFR()
|
|
{
|
|
FI = 0;
|
|
FR = 0;
|
|
}
|
|
};
|
|
|
|
// Hardware Implementation-Dependent Register 0
|
|
union UReg_HID0
|
|
{
|
|
struct
|
|
{
|
|
u32 NOOPTI : 1;
|
|
u32 : 1;
|
|
u32 BHT : 1;
|
|
u32 ABE : 1;
|
|
u32 : 1;
|
|
u32 BTIC : 1;
|
|
u32 DCFA : 1;
|
|
u32 SGE : 1;
|
|
u32 IFEM : 1;
|
|
u32 SPD : 1;
|
|
u32 DCFI : 1;
|
|
u32 ICFI : 1;
|
|
u32 DLOCK : 1;
|
|
u32 ILOCK : 1;
|
|
u32 DCE : 1;
|
|
u32 ICE : 1;
|
|
u32 NHR : 1;
|
|
u32 : 3;
|
|
u32 DPM : 1;
|
|
u32 SLEEP : 1;
|
|
u32 NAP : 1;
|
|
u32 DOZE : 1;
|
|
u32 PAR : 1;
|
|
u32 ECLK : 1;
|
|
u32 : 1;
|
|
u32 BCLK : 1;
|
|
u32 EBD : 1;
|
|
u32 EBA : 1;
|
|
u32 DBP : 1;
|
|
u32 EMCP : 1;
|
|
};
|
|
u32 Hex = 0;
|
|
};
|
|
|
|
// Hardware Implementation-Dependent Register 2
|
|
union UReg_HID2
|
|
{
|
|
struct
|
|
{
|
|
u32 : 16;
|
|
u32 DQOEE : 1;
|
|
u32 DCMEE : 1;
|
|
u32 DNCEE : 1;
|
|
u32 DCHEE : 1;
|
|
u32 DQOERR : 1;
|
|
u32 DCMERR : 1;
|
|
u32 DNCERR : 1;
|
|
u32 DCHERR : 1;
|
|
u32 DMAQL : 4;
|
|
u32 LCE : 1;
|
|
u32 PSE : 1;
|
|
u32 WPE : 1;
|
|
u32 LSQE : 1;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_HID2() = default;
|
|
explicit UReg_HID2(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
// Hardware Implementation-Dependent Register 4
|
|
union UReg_HID4
|
|
{
|
|
struct
|
|
{
|
|
u32 : 20;
|
|
u32 L2CFI : 1;
|
|
u32 L2MUM : 1;
|
|
u32 DBP : 1;
|
|
u32 LPE : 1;
|
|
u32 ST0 : 1;
|
|
u32 SBE : 1;
|
|
u32 : 1;
|
|
u32 BPD : 2;
|
|
u32 L2FM : 2;
|
|
u32 : 1;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_HID4() = default;
|
|
explicit UReg_HID4(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
// SPR1 - Page Table format
|
|
union UReg_SPR1
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u32 htaborg : 16;
|
|
u32 : 7;
|
|
u32 htabmask : 9;
|
|
};
|
|
};
|
|
|
|
// MMCR0 - Monitor Mode Control Register 0 format
|
|
union UReg_MMCR0
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u32 PMC2SELECT : 6;
|
|
u32 PMC1SELECT : 7;
|
|
u32 PMCTRIGGER : 1;
|
|
u32 PMCINTCONTROL : 1;
|
|
u32 PMC1INTCONTROL : 1;
|
|
u32 THRESHOLD : 6;
|
|
u32 INTONBITTRANS : 1;
|
|
u32 RTCSELECT : 2;
|
|
u32 DISCOUNT : 1;
|
|
u32 ENINT : 1;
|
|
u32 DMR : 1;
|
|
u32 DMS : 1;
|
|
u32 DU : 1;
|
|
u32 DP : 1;
|
|
u32 DIS : 1;
|
|
};
|
|
};
|
|
|
|
// MMCR1 - Monitor Mode Control Register 1 format
|
|
union UReg_MMCR1
|
|
{
|
|
u32 Hex;
|
|
struct
|
|
{
|
|
u32 : 22;
|
|
u32 PMC4SELECT : 5;
|
|
u32 PMC3SELECT : 5;
|
|
};
|
|
};
|
|
|
|
// Write Pipe Address Register
|
|
union UReg_WPAR
|
|
{
|
|
struct
|
|
{
|
|
u32 BNE : 1;
|
|
u32 : 4;
|
|
u32 GB_ADDR : 27;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_WPAR() = default;
|
|
explicit UReg_WPAR(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
// Direct Memory Access Upper register
|
|
union UReg_DMAU
|
|
{
|
|
struct
|
|
{
|
|
u32 DMA_LEN_U : 5;
|
|
u32 MEM_ADDR : 27;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_DMAU() = default;
|
|
explicit UReg_DMAU(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
// Direct Memory Access Lower (DMAL) register
|
|
union UReg_DMAL
|
|
{
|
|
struct
|
|
{
|
|
u32 DMA_F : 1;
|
|
u32 DMA_T : 1;
|
|
u32 DMA_LEN_L : 2;
|
|
u32 DMA_LD : 1;
|
|
u32 LC_ADDR : 27;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_DMAL() = default;
|
|
explicit UReg_DMAL(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
union UReg_BAT_Up
|
|
{
|
|
struct
|
|
{
|
|
u32 VP : 1;
|
|
u32 VS : 1;
|
|
u32 BL : 11; // Block length (aka block size mask)
|
|
u32 : 4;
|
|
u32 BEPI : 15;
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_BAT_Up() = default;
|
|
explicit UReg_BAT_Up(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
union UReg_BAT_Lo
|
|
{
|
|
struct
|
|
{
|
|
u32 PP : 2;
|
|
u32 : 1;
|
|
u32 WIMG : 4;
|
|
u32 : 10;
|
|
u32 BRPN : 15; // Physical Block Number
|
|
};
|
|
u32 Hex = 0;
|
|
|
|
UReg_BAT_Lo() = default;
|
|
explicit UReg_BAT_Lo(u32 hex_) : Hex{hex_} {}
|
|
};
|
|
|
|
union UReg_PTE
|
|
{
|
|
struct
|
|
{
|
|
u64 API : 6;
|
|
u64 H : 1;
|
|
u64 VSID : 24;
|
|
u64 V : 1;
|
|
u64 PP : 2;
|
|
u64 : 1;
|
|
u64 WIMG : 4;
|
|
u64 C : 1;
|
|
u64 R : 1;
|
|
u64 : 3;
|
|
u64 RPN : 20;
|
|
};
|
|
|
|
u64 Hex = 0;
|
|
u32 Hex32[2];
|
|
};
|
|
|
|
//
|
|
// --- Gekko Types and Defs ---
|
|
//
|
|
|
|
// branches
|
|
enum
|
|
{
|
|
BO_BRANCH_IF_CTR_0 = 2, // 3
|
|
BO_DONT_DECREMENT_FLAG = 4, // 2
|
|
BO_BRANCH_IF_TRUE = 8, // 1
|
|
BO_DONT_CHECK_CONDITION = 16, // 0
|
|
};
|
|
|
|
// Special purpose register indices
|
|
enum
|
|
{
|
|
SPR_XER = 1,
|
|
SPR_LR = 8,
|
|
SPR_CTR = 9,
|
|
SPR_DSISR = 18,
|
|
SPR_DAR = 19,
|
|
SPR_DEC = 22,
|
|
SPR_SDR = 25,
|
|
SPR_SRR0 = 26,
|
|
SPR_SRR1 = 27,
|
|
SPR_TL = 268,
|
|
SPR_TU = 269,
|
|
SPR_TL_W = 284,
|
|
SPR_TU_W = 285,
|
|
SPR_PVR = 287,
|
|
SPR_SPRG0 = 272,
|
|
SPR_SPRG1 = 273,
|
|
SPR_SPRG2 = 274,
|
|
SPR_SPRG3 = 275,
|
|
SPR_EAR = 282,
|
|
SPR_IBAT0U = 528,
|
|
SPR_IBAT0L = 529,
|
|
SPR_IBAT1U = 530,
|
|
SPR_IBAT1L = 531,
|
|
SPR_IBAT2U = 532,
|
|
SPR_IBAT2L = 533,
|
|
SPR_IBAT3U = 534,
|
|
SPR_IBAT3L = 535,
|
|
SPR_DBAT0U = 536,
|
|
SPR_DBAT0L = 537,
|
|
SPR_DBAT1U = 538,
|
|
SPR_DBAT1L = 539,
|
|
SPR_DBAT2U = 540,
|
|
SPR_DBAT2L = 541,
|
|
SPR_DBAT3U = 542,
|
|
SPR_DBAT3L = 543,
|
|
SPR_IBAT4U = 560,
|
|
SPR_IBAT4L = 561,
|
|
SPR_IBAT5U = 562,
|
|
SPR_IBAT5L = 563,
|
|
SPR_IBAT6U = 564,
|
|
SPR_IBAT6L = 565,
|
|
SPR_IBAT7U = 566,
|
|
SPR_IBAT7L = 567,
|
|
SPR_DBAT4U = 568,
|
|
SPR_DBAT4L = 569,
|
|
SPR_DBAT5U = 570,
|
|
SPR_DBAT5L = 571,
|
|
SPR_DBAT6U = 572,
|
|
SPR_DBAT6L = 573,
|
|
SPR_DBAT7U = 574,
|
|
SPR_DBAT7L = 575,
|
|
SPR_GQR0 = 912,
|
|
SPR_HID0 = 1008,
|
|
SPR_HID1 = 1009,
|
|
SPR_HID2 = 920,
|
|
SPR_HID4 = 1011,
|
|
SPR_WPAR = 921,
|
|
SPR_DMAU = 922,
|
|
SPR_DMAL = 923,
|
|
SPR_ECID_U = 924,
|
|
SPR_ECID_M = 925,
|
|
SPR_ECID_L = 926,
|
|
SPR_L2CR = 1017,
|
|
|
|
SPR_UMMCR0 = 936,
|
|
SPR_MMCR0 = 952,
|
|
SPR_PMC1 = 953,
|
|
SPR_PMC2 = 954,
|
|
|
|
SPR_UMMCR1 = 940,
|
|
SPR_MMCR1 = 956,
|
|
SPR_PMC3 = 957,
|
|
SPR_PMC4 = 958,
|
|
};
|
|
|
|
// Exceptions
|
|
enum
|
|
{
|
|
EXCEPTION_DECREMENTER = 0x00000001,
|
|
EXCEPTION_SYSCALL = 0x00000002,
|
|
EXCEPTION_EXTERNAL_INT = 0x00000004,
|
|
EXCEPTION_DSI = 0x00000008,
|
|
EXCEPTION_ISI = 0x00000010,
|
|
EXCEPTION_ALIGNMENT = 0x00000020,
|
|
EXCEPTION_FPU_UNAVAILABLE = 0x00000040,
|
|
EXCEPTION_PROGRAM = 0x00000080,
|
|
EXCEPTION_PERFORMANCE_MONITOR = 0x00000100,
|
|
|
|
EXCEPTION_FAKE_MEMCHECK_HIT = 0x00000200,
|
|
};
|
|
|
|
constexpr s32 SignExt16(s16 x)
|
|
{
|
|
return (s32)x;
|
|
}
|
|
constexpr s32 SignExt26(u32 x)
|
|
{
|
|
return x & 0x2000000 ? (s32)(x | 0xFC000000) : (s32)(x);
|
|
}
|