Adding instruction table and basic PPC state.
Can decode a single instruction.
This commit is contained in:
@@ -29,7 +29,7 @@ xe_memory_ref xe_memory_retain(xe_memory_ref memory);
|
||||
void xe_memory_release(xe_memory_ref memory);
|
||||
|
||||
size_t xe_memory_get_length(xe_memory_ref memory);
|
||||
void *xe_memory_addr(xe_memory_ref memory, uint32_t guest_addr);
|
||||
uint8_t *xe_memory_addr(xe_memory_ref memory, uint32_t guest_addr);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_MEMORY_H_
|
||||
|
||||
18
include/xenia/cpu/ppc.h
Normal file
18
include/xenia/cpu/ppc.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_H_
|
||||
#define XENIA_CPU_PPC_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
#include <xenia/cpu/ppc/instr.h>
|
||||
#include <xenia/cpu/ppc/state.h>
|
||||
|
||||
#endif // XENIA_CPU_PPC_H_
|
||||
137
include/xenia/cpu/ppc/instr.h
Normal file
137
include/xenia/cpu/ppc/instr.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_INSTR_H_
|
||||
#define XENIA_CPU_PPC_INSTR_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
typedef enum {
|
||||
kXEPPCInstrFormatI = 0,
|
||||
kXEPPCInstrFormatB = 1,
|
||||
kXEPPCInstrFormatSC = 2,
|
||||
kXEPPCInstrFormatD = 3,
|
||||
kXEPPCInstrFormatDS = 4,
|
||||
kXEPPCInstrFormatX = 5,
|
||||
kXEPPCInstrFormatXL = 6,
|
||||
kXEPPCInstrFormatXFX = 7,
|
||||
kXEPPCInstrFormatXFL = 8,
|
||||
kXEPPCInstrFormatXS = 9,
|
||||
kXEPPCInstrFormatXO = 10,
|
||||
kXEPPCInstrFormatA = 11,
|
||||
kXEPPCInstrFormatM = 12,
|
||||
kXEPPCInstrFormatMD = 13,
|
||||
kXEPPCInstrFormatMDS = 14,
|
||||
kXEPPCInstrFormatVA = 15,
|
||||
kXEPPCInstrFormatVX = 16,
|
||||
kXEPPCInstrFormatVXR = 17,
|
||||
} xe_ppc_instr_format_e;
|
||||
|
||||
typedef enum {
|
||||
kXEPPCInstrTypeGeneral = (1 << 0),
|
||||
kXEPPCInstrTypeBranch = (1 << 1),
|
||||
kXEPPCInstrTypeBranchCond = kXEPPCInstrTypeBranch | (1 << 2),
|
||||
kXEPPCInstrTypeBranchAlways = kXEPPCInstrTypeBranch | (1 << 3),
|
||||
kXEPPCInstrTypeSyscall = (1 << 4),
|
||||
} xe_ppc_instr_type_e;
|
||||
|
||||
typedef enum {
|
||||
kXEPPCInstrFlagReserved = 0,
|
||||
} xe_ppc_instr_flag_e;
|
||||
|
||||
|
||||
struct xe_ppc_instr_type;
|
||||
typedef struct xe_ppc_instr_type xe_ppc_instr_type_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
xe_ppc_instr_type_t *type;
|
||||
uint32_t address;
|
||||
|
||||
union {
|
||||
uint32_t code;
|
||||
|
||||
// kXEPPCInstrFormatI
|
||||
struct {
|
||||
uint32_t LK : 1;
|
||||
uint32_t AA : 1;
|
||||
uint32_t LI : 24;
|
||||
uint32_t OPCD : 6;
|
||||
} I;
|
||||
// kXEPPCInstrFormatB
|
||||
struct {
|
||||
uint32_t LK : 1;
|
||||
uint32_t AA : 1;
|
||||
uint32_t BD : 14;
|
||||
uint32_t BI : 5;
|
||||
uint32_t BO : 5;
|
||||
uint32_t OPCD : 6;
|
||||
} B;
|
||||
|
||||
// kXEPPCInstrFormatSC
|
||||
struct {
|
||||
uint32_t SIMM : 16;
|
||||
uint32_t A : 5;
|
||||
uint32_t D : 5;
|
||||
uint32_t OPCD : 6;
|
||||
} D;
|
||||
// kXEPPCInstrFormatDS
|
||||
struct {
|
||||
uint32_t : 2;
|
||||
uint32_t ds : 14;
|
||||
uint32_t A : 5;
|
||||
uint32_t S : 5;
|
||||
uint32_t OPCD : 6;
|
||||
} DS;
|
||||
// kXEPPCInstrFormatX
|
||||
// kXEPPCInstrFormatXL
|
||||
struct {
|
||||
uint32_t : 1;
|
||||
uint32_t : 10;
|
||||
uint32_t spr : 10;
|
||||
uint32_t D : 5;
|
||||
uint32_t OPCD : 6;
|
||||
} XFX;
|
||||
// kXEPPCInstrFormatXFL
|
||||
// kXEPPCInstrFormatXS
|
||||
// kXEPPCInstrFormatXO
|
||||
// kXEPPCInstrFormatA
|
||||
// kXEPPCInstrFormatM
|
||||
// kXEPPCInstrFormatMD
|
||||
// kXEPPCInstrFormatMDS
|
||||
// kXEPPCInstrFormatVA
|
||||
// kXEPPCInstrFormatVX
|
||||
// kXEPPCInstrFormatVXR
|
||||
} data;
|
||||
} xe_ppc_instr_t;
|
||||
|
||||
typedef struct {
|
||||
xe_ppc_instr_t instr;
|
||||
|
||||
// TODO(benvanik): registers changed, special bits, etc
|
||||
} xe_ppc_dec_instr_t;
|
||||
|
||||
typedef int (*xe_ppc_emit_fn)(/* emit context */ xe_ppc_instr_t *instr);
|
||||
|
||||
struct xe_ppc_instr_type {
|
||||
uint32_t opcode;
|
||||
uint32_t format; // xe_ppc_instr_format_e
|
||||
uint32_t type; // xe_ppc_instr_type_e
|
||||
uint32_t flags; // xe_ppc_instr_flag_e
|
||||
char name[16];
|
||||
|
||||
xe_ppc_emit_fn emit;
|
||||
};
|
||||
|
||||
xe_ppc_instr_type_t *xe_ppc_get_instr_type(uint32_t code);
|
||||
int xe_ppc_register_instr_emit(uint32_t code, xe_ppc_emit_fn emit);
|
||||
|
||||
#endif // XENIA_CPU_PPC_INSTR_H_
|
||||
|
||||
111
include/xenia/cpu/ppc/state.h
Normal file
111
include/xenia/cpu/ppc/state.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CPU_PPC_STATE_H_
|
||||
#define XENIA_CPU_PPC_STATE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
typedef struct XECACHEALIGN64 {
|
||||
uint64_t r[32]; // General purpose registers
|
||||
xefloat4_t v[128]; // VMX128 vector registers
|
||||
double f[32]; // Floating-point registers
|
||||
|
||||
uint32_t pc; // Current PC (CIA)
|
||||
uint32_t npc; // Next PC (NIA)
|
||||
uint64_t xer; // XER register
|
||||
uint64_t lr; // Link register
|
||||
uint64_t ctr; // Count register
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t lt :1; // Negative (LT) - result is negative
|
||||
uint8_t gt :1; // Positive (GT) - result is positive (and not zero)
|
||||
uint8_t eq :1; // Zero (EQ) - result is zero or a stwcx/stdcx completed successfully
|
||||
uint8_t so :1; // Summary Overflow (SO) - copy of XER[SO]
|
||||
} cr0;
|
||||
struct {
|
||||
uint8_t fx :1; // FP exception summary - copy of FPSCR[FX]
|
||||
uint8_t fex :1; // FP enabled exception summary - copy of FPSCR[FEX]
|
||||
uint8_t vx :1; // FP invalid operation exception summary - copy of FPSCR[VX]
|
||||
uint8_t ox :1; // FP overflow exception - copy of FPSCR[OX]
|
||||
} cr1;
|
||||
} cr; // Condition register
|
||||
|
||||
union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint8_t fx :1; // FP exception summary -- sticky
|
||||
uint8_t fex :1; // FP enabled exception summary
|
||||
uint8_t vx :1; // FP invalid operation exception summary
|
||||
uint8_t ox :1; // FP overflow exception -- sticky
|
||||
uint8_t ux :1; // FP underflow exception -- sticky
|
||||
uint8_t zx :1; // FP zero divide exception -- sticky
|
||||
uint8_t xx :1; // FP inexact exception -- sticky
|
||||
uint8_t vxsnan :1; // FP invalid op exception: SNaN -- sticky
|
||||
uint8_t vxisi :1; // FP invalid op exception: infinity - infinity -- sticky
|
||||
uint8_t vxidi :1; // FP invalid op exception: infinity / infinity -- sticky
|
||||
uint8_t vxzdz :1; // FP invalid op exception: 0 / 0 -- sticky
|
||||
uint8_t vximz :1; // FP invalid op exception: infinity * 0 -- sticky
|
||||
uint8_t vxvc :1; // FP invalid op exception: invalid compare -- sticky
|
||||
uint8_t fr :1; // FP fraction rounded
|
||||
uint8_t fi :1; // FP fraction inexact
|
||||
uint8_t fprf_c :1; // FP result class
|
||||
uint8_t fprf_lt :1; // FP result less than or negative (FL or <)
|
||||
uint8_t fprf_gt :1; // FP result greater than or positive (FG or >)
|
||||
uint8_t fprf_eq :1; // FP result equal or zero (FE or =)
|
||||
uint8_t fprf_un :1; // FP result unordered or NaN (FU or ?)
|
||||
uint8_t reserved :1;
|
||||
uint8_t vxsoft :1; // FP invalid op exception: software request -- sticky
|
||||
uint8_t vxsqrt :1; // FP invalid op exception: invalid sqrt -- sticky
|
||||
uint8_t vxcvi :1; // FP invalid op exception: invalid integer convert -- sticky
|
||||
uint8_t ve :1; // FP invalid op exception enable
|
||||
uint8_t oe :1; // IEEE floating-point overflow exception enable
|
||||
uint8_t ue :1; // IEEE floating-point underflow exception enable
|
||||
uint8_t ze :1; // IEEE floating-point zero divide exception enable
|
||||
uint8_t xe :1; // IEEE floating-point inexact exception enable
|
||||
uint8_t ni :1; // Floating-point non-IEEE mode
|
||||
uint8_t rn :2; // FP rounding control: 00 = nearest
|
||||
// 01 = toward zero
|
||||
// 10 = toward +infinity
|
||||
// 11 = toward -infinity
|
||||
} bits;
|
||||
} fpscr; // Floating-point status and control register
|
||||
} xe_ppc_registers_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
xe_ppc_registers_t registers;
|
||||
} xe_ppc_state_t;
|
||||
|
||||
|
||||
namespace XE_PPC_FPRF {
|
||||
enum XE_PPC_FPRF_e {
|
||||
QUIET_NAN = 0x00088000,
|
||||
NEG_INFINITY = 0x00090000,
|
||||
NEG_NORMALIZED = 0x00010000,
|
||||
NEG_DENORMALIZED = 0x00018000,
|
||||
NEG_ZERO = 0x00048000,
|
||||
POS_ZERO = 0x00040000,
|
||||
POS_DENORMALIZED = 0x00028000,
|
||||
POS_NORMALIZED = 0x00020000,
|
||||
POS_INFINITY = 0x000A0000,
|
||||
};
|
||||
} // XE_PPC_FPRF
|
||||
uint32_t xe_ppc_get_fprf(const xe_ppc_registers_t *r) {
|
||||
return r->fpscr.value & 0x000F8000;
|
||||
}
|
||||
void xe_ppc_set_fprf(xe_ppc_registers_t *r, const uint32_t v) {
|
||||
r->fpscr.value = (r->fpscr.value & ~0x000F8000) | v;
|
||||
}
|
||||
|
||||
|
||||
#endif // XENIA_CPU_PPC_STATE_H_
|
||||
@@ -95,6 +95,9 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
|
||||
#endif // GNUC
|
||||
#endif // !MIN
|
||||
|
||||
#define XEBITMASK(a, b) (((unsigned) -1 >> (31 - (b))) & ~((1U << (a)) - 1))
|
||||
#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a)
|
||||
|
||||
#define XEFAIL() goto XECLEANUP
|
||||
#define XEEXPECT(expr) if (!(expr) ) { goto XECLEANUP; }
|
||||
#define XEEXPECTTRUE(expr) if (!(expr) ) { goto XECLEANUP; }
|
||||
@@ -106,4 +109,21 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
|
||||
#define XEIGNORE(expr) do { (void)(expr); } while(0)
|
||||
|
||||
|
||||
typedef struct XECACHEALIGN {
|
||||
union {
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
float f4[4];
|
||||
struct {
|
||||
uint64_t low;
|
||||
uint64_t high;
|
||||
};
|
||||
};
|
||||
} xefloat4_t;
|
||||
|
||||
|
||||
#endif // XENIA_TYPES_H_
|
||||
|
||||
Reference in New Issue
Block a user