Screw convention; moving include files alongside source files.

They now will show up in xcode/etc.
This commit is contained in:
Ben Vanik
2013-02-06 02:19:50 -08:00
parent 3dfd9c4b00
commit 88431eadce
151 changed files with 290 additions and 200 deletions

72
src/xenia/assert.h Normal file
View File

@@ -0,0 +1,72 @@
/**
******************************************************************************
* 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_ASSERT_H_
#define XENIA_ASSERT_H_
#include <assert.h>
#include <xenia/assert.h>
#include <xenia/config.h>
#include <xenia/platform.h>
#include <xenia/platform_includes.h>
#include <xenia/types.h>
#if XE_COMPILER(MSVC)
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
#if !defined(__WFILE__)
#define WIDEN2(x) L##x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#define __WFUNCTION__ WIDEN(__FUNCTION__)
#endif
#define XE_CURRENT_FILE __WFILE__
#define XE_CURRENT_FUNCTION __WFUNCTION__
#else
#define XE_CURRENT_FILE __FILE__
#define XE_CURRENT_FUNCTION __FUNCTION__
#endif // MSVC
#define XE_CURRENT_LINE __LINE__
#define __XE_ASSERT(expr) assert(expr)
#if XE_OPTION(ENABLE_ASSERTS)
#define XEASSERTCORE(expr) __XE_ASSERT(expr)
#else
#define XEASSERTCORE(expr) XE_EMPTY_MACRO
#endif // ENABLE_ASSERTS
#define XEASSERTALWAYS() XEASSERTCORE( 0 )
#define XEASSERT(expr) XEASSERTCORE( (expr) )
#define XEASSERTTRUE(expr) XEASSERTCORE( (expr) )
#define XEASSERTFALSE(expr) XEASSERTCORE(!(expr) )
#define XEASSERTZERO(expr) XEASSERTCORE( (expr) == 0 )
#define XEASSERTNOTZERO(expr) XEASSERTCORE( (expr) != 0 )
#define XEASSERTNULL(expr) XEASSERTCORE( (expr) == NULL )
#define XEASSERTNOTNULL(expr) XEASSERTCORE( (expr) != NULL )
#if XE_COMPILER(MSVC)
// http://msdn.microsoft.com/en-us/library/bb918086.aspx
// TODO(benvanik): if 2010+, use static_assert?
// http://msdn.microsoft.com/en-us/library/dd293588.aspx
#define XESTATICASSERT(expr, message) _STATIC_ASSERT(expr)
//#elif XE_COMPILER(GNUC)
// http://stackoverflow.com/questions/3385515/static-assert-in-c
//#define XESTATICASSERT(expr, message) ({ extern int __attribute__((error("assertion failure: '" #expr "' not true - " #message))) compile_time_check(); ((expr)?0:compile_time_check()),0; })
#else
// http://stackoverflow.com/questions/3385515/static-assert-in-c
#define XESTATICASSERT3(expr, L) typedef char static_assertion_##L[(expr)?1:-1]
#define XESTATICASSERT2(expr, L) XESTATICASSERT3(expr, L)
#define XESTATICASSERT(expr, message) XESTATICASSERT2(expr, __LINE__)
#endif // MSVC
#endif // XENIA_ASSERT_H_

81
src/xenia/atomic.h Normal file
View File

@@ -0,0 +1,81 @@
/**
******************************************************************************
* 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_ATOMIC_H_
#define XENIA_ATOMIC_H_
#include <xenia/platform.h>
#include <xenia/platform_includes.h>
// These functions are modeled off of the Apple OSAtomic routines
// http://developer.apple.com/library/mac/#documentation/DriversKernelHardware/Reference/libkern_ref/OSAtomic_h/
#if XE_LIKE(OSX)
#include <libkern/OSAtomic.h>
#define xe_atomic_inc_32(value) \
OSAtomicIncrement32Barrier(value)
#define xe_atomic_dec_32(value) \
OSAtomicDecrement32Barrier(value)
#define xe_atomic_add_32(amount, value) \
((void)OSAtomicAdd32Barrier(amount, value))
#define xe_atomic_sub_32(amount, value) \
((void)OSAtomicAdd32Barrier(-amount, value))
#define xe_atomic_cas_32(oldValue, newValue, value) \
OSAtomicCompareAndSwap32Barrier(oldValue, newValue, value)
typedef OSQueueHead xe_atomic_stack_t;
#define xe_atomic_stack_init(stack) \
*(stack) = (OSQueueHead)OS_ATOMIC_QUEUE_INIT
#define xe_atomic_stack_enqueue(stack, item, offset) \
OSAtomicEnqueue((OSQueueHead*)stack, item, offset)
#define xe_atomic_stack_dequeue(stack, offset) \
OSAtomicDequeue((OSQueueHead*)stack, offset)
#elif XE_LIKE(WIN32)
#define xe_atomic_inc_32(value) \
InterlockedIncrement((volatile LONG*)value)
#define xe_atomic_dec_32(value) \
InterlockedDecrement((volatile LONG*)value)
#define xe_atomic_add_32(amount, value) \
((void)InterlockedExchangeAdd((volatile LONG*)value, amount))
#define xe_atomic_sub_32(amount, value) \
((void)InterlockedExchangeSubtract((volatile unsigned*)value, amount))
#define xe_atomic_vas_32(oldValue, newValue, value) \
(InterlockedCompareExchange((volatile LONG*)value, newValue, oldValue) == oldValue)
typedef SLIST_HEADER xe_atomic_stack_t;
#define xe_atomic_stack_init(stack) \
InitializeSListHead((PSLIST_HEADER)stack)
#define xe_atomic_stack_enqueue(stack, item, offset) \
XEIGNORE(InterlockedPushEntrySList((PSLIST_HEADER)stack, (PSLIST_ENTRY)((byte*)item + offset)))
XEFORCEINLINE void* xe_atomic_stack_dequeue(xe_atomic_stack_t* stack,
const size_t offset) {
void* ptr = (void*)InterlockedPopEntrySList((PSLIST_HEADER)stack);
if (ptr) {
return (void*)(((uint8_t*)ptr) - offset);
} else {
return NULL;
}
}
#elif XE_LIKE(POSIX)
#error TODO(benvanik): POSIX atomic primitives
#else
#error No atomic primitives defined for this platform/cpu combination.
#endif // OSX
#endif // XENIA_ATOMIC_H_

77
src/xenia/byte_order.h Normal file
View File

@@ -0,0 +1,77 @@
/**
******************************************************************************
* 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_BYTE_ORDER_H_
#define XENIA_BYTE_ORDER_H_
#include <xenia/platform.h>
#include <xenia/types.h>
#if XE_COMPILER(MSVC)
#define XESWAP16 _byteswap_ushort
#define XESWAP32 _byteswap_ulong
#define XESWAP64 _byteswap_uint64
#elif XE_LIKE(OSX)
#include <libkern/OSByteOrder.h>
#define XESWAP16 OSSwapInt16
#define XESWAP32 OSSwapInt32
#define XESWAP64 OSSwapInt64
#else
#define XESWAP16 bswap_16
#define XESWAP32 bswap_32
#define XESWAP64 bswap_64
#endif
#if XE_CPU(BIGENDIAN)
#define XESWAP16BE(p) (p)
#define XESWAP32BE(p) (p)
#define XESWAP64BE(p) (p)
#define XESWAP16LE(p) XESWAP16(p)
#define XESWAP32LE(p) XESWAP32(p)
#define XESWAP64LE(p) XESWAP64(p)
#else
#define XESWAP16BE(p) XESWAP16(p)
#define XESWAP32BE(p) XESWAP32(p)
#define XESWAP64BE(p) XESWAP64(p)
#define XESWAP16LE(p) (p)
#define XESWAP32LE(p) (p)
#define XESWAP64LE(p) (p)
#endif
#define XEGETINT8BE(p) ( (int8_t)(*(p)))
#define XEGETUINT8BE(p) ( (uint8_t)(*(p)))
#define XEGETINT16BE(p) ( (int16_t)XESWAP16BE(*(uint16_t*)(p)))
#define XEGETUINT16BE(p) ((uint16_t)XESWAP16BE(*(uint16_t*)(p)))
#define XEGETINT32BE(p) ( (int32_t)XESWAP32BE(*(uint32_t*)(p)))
#define XEGETUINT32BE(p) ((uint32_t)XESWAP32BE(*(uint32_t*)(p)))
#define XEGETINT64BE(p) ( (int64_t)XESWAP64BE(*(uint64_t*)(p)))
#define XEGETUINT64BE(p) ((uint64_t)XESWAP64BE(*(uint64_t*)(p)))
#define XEGETINT8LE(p) ( (int8_t)(*(p)))
#define XEGETUINT8LE(p) ( (uint8_t)(*(p)))
#define XEGETINT16LE(p) ( (int16_t)XESWAP16LE(*(uint16_t*)(p)))
#define XEGETUINT16LE(p) ((uint16_t)XESWAP16LE(*(uint16_t*)(p)))
#define XEGETINT32LE(p) ( (int32_t)XESWAP32LE(*(uint32_t*)(p)))
#define XEGETUINT32LE(p) ((uint32_t)XESWAP32LE(*(uint32_t*)(p)))
#define XEGETINT64LE(p) ( (int64_t)XESWAP64LE(*(uint64_t*)(p)))
#define XEGETUINT64LE(p) ((uint64_t)XESWAP64LE(*(uint64_t*)(p)))
#define XESETINT8BE(p, v) (*( (int8_t*)(p)) = (int8_t)v)
#define XESETUINT8BE(p, v) (*( (uint8_t*)(p)) = (uint8_t)v)
#define XESETINT16BE(p, v) (*( (int16_t*)(p)) = XESWAP16BE( (int16_t)v))
#define XESETUINT16BE(p, v) (*((uint16_t*)(p)) = XESWAP16BE((uint16_t)v))
#define XESETINT32BE(p, v) (*( (int32_t*)(p)) = XESWAP32BE( (int32_t)v))
#define XESETUINT32BE(p, v) (*((uint32_t*)(p)) = XESWAP32BE((uint32_t)v))
#define XESETINT64BE(p, v) (*( (int64_t*)(p)) = XESWAP64BE( (int64_t)v))
#define XESETUINT64BE(p, v) (*((uint64_t*)(p)) = XESWAP64BE((uint64_t)v))
#endif // XENIA_BYTE_ORDER_H_

24
src/xenia/common.h Normal file
View File

@@ -0,0 +1,24 @@
/**
******************************************************************************
* 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_COMMON_H_
#define XENIA_COMMON_H_
#include <xenia/assert.h>
#include <xenia/atomic.h>
#include <xenia/byte_order.h>
#include <xenia/config.h>
#include <xenia/logging.h>
#include <xenia/malloc.h>
#include <xenia/platform.h>
#include <xenia/platform_includes.h>
#include <xenia/string.h>
#include <xenia/types.h>
#endif // XENIA_COMMON_H_

37
src/xenia/config.h Normal file
View File

@@ -0,0 +1,37 @@
/**
******************************************************************************
* 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_CONFIG_H_
#define XENIA_CONFIG_H_
#define XE_OPTION(NAME) (defined XE_OPTION_##NAME && XE_OPTION_##NAME)
// Enable compile-time and runtime-time assertions.
#define XE_OPTION_ENABLE_ASSERTS 1
// Enable general logging.
#define XE_OPTION_ENABLE_LOGGING 1
#define XE_OPTION_LOG_ERROR 1
#define XE_OPTION_LOG_WARNING 1
#define XE_OPTION_LOG_INFO 1
#define XE_OPTION_LOG_DEBUG 1
#define XE_OPTION_LOG_CPU 1
#define XE_OPTION_LOG_SDB 0
#define XE_OPTION_LOG_GPU 1
#define XE_OPTION_LOG_KERNEL 1
#define XE_OPTION_LOG_FS 1
// TODO(benvanik): make this a runtime option
#define XE_OPTION_OPTIMIZED 0
#endif // XENIA_CONFIG_H_

22
src/xenia/core.h Normal file
View File

@@ -0,0 +1,22 @@
/**
******************************************************************************
* 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_CORE_H_
#define XENIA_CORE_H_
#include <xenia/common.h>
#include <xenia/core/file.h>
#include <xenia/core/memory.h>
#include <xenia/core/mmap.h>
#include <xenia/core/mutex.h>
#include <xenia/core/pal.h>
#include <xenia/core/ref.h>
#endif // XENIA_CORE_H_

37
src/xenia/core/file.h Normal file
View File

@@ -0,0 +1,37 @@
/**
******************************************************************************
* 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_CORE_FILE_H_
#define XENIA_CORE_FILE_H_
#include <xenia/common.h>
#include <xenia/core/pal.h>
#include <xenia/core/ref.h>
struct xe_file;
typedef struct xe_file* xe_file_ref;
typedef enum {
kXEFileModeRead = (1 << 0),
kXEFileModeWrite = (1 << 1),
} xe_file_mode;
xe_file_ref xe_file_open(xe_pal_ref pal, const xe_file_mode mode,
const xechar_t *path);
xe_file_ref xe_file_retain(xe_file_ref file);
void xe_file_release(xe_file_ref file);
size_t xe_file_get_length(xe_file_ref file);
size_t xe_file_read(xe_file_ref file, const size_t offset,
uint8_t *buffer, const size_t buffer_size);
#endif // XENIA_CORE_FILE_H_

46
src/xenia/core/memory.h Normal file
View File

@@ -0,0 +1,46 @@
/**
******************************************************************************
* 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_CORE_MEMORY_H_
#define XENIA_CORE_MEMORY_H_
#include <xenia/common.h>
#include <xenia/core/pal.h>
#include <xenia/core/ref.h>
typedef struct {
int reserved;
} xe_memory_options_t;
struct xe_memory;
typedef struct xe_memory* xe_memory_ref;
xe_memory_ref xe_memory_create(xe_pal_ref pal, xe_memory_options_t options);
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);
uint8_t *xe_memory_addr(xe_memory_ref memory, uint32_t guest_addr);
uint32_t xe_memory_search_aligned(xe_memory_ref memory, uint32_t start,
uint32_t end, const uint32_t *values,
const size_t value_count);
// These methods slice off memory from the virtual address space.
// They should only be used by kernel modules that know what they are doing.
uint32_t xe_memory_heap_alloc(xe_memory_ref memory, uint32_t base_addr,
uint32_t size, uint32_t flags);
uint32_t xe_memory_heap_free(xe_memory_ref memory, uint32_t addr,
uint32_t flags);
#endif // XENIA_CORE_MEMORY_H_

32
src/xenia/core/mmap.h Normal file
View File

@@ -0,0 +1,32 @@
/**
******************************************************************************
* 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_CORE_MMAP_H_
#define XENIA_CORE_MMAP_H_
#include <xenia/common.h>
#include <xenia/core/file.h>
#include <xenia/core/pal.h>
#include <xenia/core/ref.h>
struct xe_mmap;
typedef struct xe_mmap* xe_mmap_ref;
xe_mmap_ref xe_mmap_open(xe_pal_ref pal, const xe_file_mode mode,
const xechar_t *path,
const size_t offset, const size_t length);
xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap);
void xe_mmap_release(xe_mmap_ref mmap);
uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap);
size_t xe_mmap_get_length(xe_mmap_ref mmap);
#endif // XENIA_CORE_MMAP_H_

27
src/xenia/core/mutex.h Normal file
View File

@@ -0,0 +1,27 @@
/**
******************************************************************************
* 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_CORE_MUTEX_H_
#define XENIA_CORE_MUTEX_H_
#include <xenia/common.h>
typedef struct xe_mutex xe_mutex_t;
xe_mutex_t* xe_mutex_alloc(uint32_t spin_count);
void xe_mutex_free(xe_mutex_t* mutex);
int xe_mutex_lock(xe_mutex_t* mutex);
int xe_mutex_trylock(xe_mutex_t* mutex);
int xe_mutex_unlock(xe_mutex_t* mutex);
#endif // XENIA_CORE_MUTEX_H_

31
src/xenia/core/pal.h Normal file
View File

@@ -0,0 +1,31 @@
/**
******************************************************************************
* 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_CORE_PAL_H_
#define XENIA_CORE_PAL_H_
#include <xenia/common.h>
#include <xenia/core/ref.h>
typedef struct {
int reserved;
} xe_pal_options_t;
struct xe_pal;
typedef struct xe_pal* xe_pal_ref;
xe_pal_ref xe_pal_create(xe_pal_options_t options);
xe_pal_ref xe_pal_retain(xe_pal_ref pal);
void xe_pal_release(xe_pal_ref pal);
#endif // XENIA_CORE_PAL_H_

29
src/xenia/core/ref.h Normal file
View File

@@ -0,0 +1,29 @@
/**
******************************************************************************
* 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_CORE_REF_H_
#define XENIA_CORE_REF_H_
#include <xenia/common.h>
typedef struct {
volatile int32_t count;
} xe_ref_t;
typedef xe_ref_t* xe_ref;
typedef void (*xe_ref_dealloc_t)(xe_ref);
void xe_ref_init(xe_ref ref);
void xe_ref_retain(xe_ref ref);
void xe_ref_release(xe_ref ref, xe_ref_dealloc_t dealloc);
#endif // XENIA_CORE_REF_H_

View File

@@ -2,9 +2,15 @@
{
'sources': [
'file.cc',
'file.h',
'memory.cc',
'memory.h',
'mmap.h',
'mutex.h',
'pal.cc',
'pal.h',
'ref.cc',
'ref.h',
],
'conditions': [

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "cpu/codegen/emit.h"
#include <xenia/cpu/codegen/emit.h>
#include <llvm/IR/Intrinsics.h>
@@ -263,8 +263,56 @@ XEDISASMR(divwx, 0x7C0003D6, XO )(InstrData& i, InstrDisasm& d) {
return d.Finish();
}
XEEMITTER(divwx, 0x7C0003D6, XO )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
// dividend[0:31] <- (RA)[32:63]
// divisor[0:31] <- (RB)[32:63]
// if divisor = 0 then
// if OE = 1 then
// XER[OV] <- 1
// return
// RT[32:63] <- dividend ÷ divisor
// RT[0:31] <- undefined
Value* dividend = b.CreateTrunc(g.gpr_value(i.XO.RA), b.getInt32Ty());
Value* divisor = b.CreateTrunc(g.gpr_value(i.XO.RB), b.getInt32Ty());
// Note that we skip the zero handling block and just avoid the divide if
// we are OE=0.
BasicBlock* zero_bb = i.XO.OE ?
BasicBlock::Create(*g.context(), "", g.gen_fn()) : NULL;
BasicBlock* nonzero_bb = BasicBlock::Create(*g.context(), "", g.gen_fn());
BasicBlock* after_bb = BasicBlock::Create(*g.context(), "", g.gen_fn());
b.CreateCondBr(b.CreateICmpEQ(divisor, b.getInt32(0)),
i.XO.OE ? zero_bb : after_bb, nonzero_bb);
if (zero_bb) {
// Divisor was zero - do XER update.
b.SetInsertPoint(zero_bb);
g.update_xer_with_overflow(b.getInt1(1));
b.CreateBr(after_bb);
}
// Divide.
b.SetInsertPoint(nonzero_bb);
Value* v = b.CreateSDiv(dividend, divisor);
v = b.CreateSExt(v, b.getInt64Ty());
g.update_gpr_value(i.XO.RT, v);
// If we are OE=1 we need to clear the overflow bit.
if (i.XO.OE) {
g.update_xer_with_overflow(b.getInt1(0));
}
if (i.XO.Rc) {
// With cr0 update.
g.update_cr_with_cond(0, v, b.getInt64(0), true);
}
b.CreateBr(after_bb);
// Resume.
b.SetInsertPoint(after_bb);
return 0;
}
XEDISASMR(divwux, 0x7C000396, XO )(InstrData& i, InstrDisasm& d) {
@@ -449,8 +497,41 @@ XEDISASMR(negx, 0x7C0000D0, XO )(InstrData& i, InstrDisasm& d) {
return d.Finish();
}
XEEMITTER(negx, 0x7C0000D0, XO )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
// RT <- ¬(RA) + 1
if (i.XO.OE) {
// With XER update.
// This is a different codepath as we need to use llvm.ssub.with.overflow.
// if RA == 0x8000000000000000 then no-op and set OV=1
// This may just magically do that...
Function* ssub_with_overflow = Intrinsic::getDeclaration(
g.gen_module(), Intrinsic::ssub_with_overflow, b.getInt64Ty());
Value* v = b.CreateCall2(ssub_with_overflow,
b.getInt64(0), g.gpr_value(i.XO.RA));
Value* v0 = b.CreateExtractValue(v, 0);
g.update_gpr_value(i.XO.RT, v0);
g.update_xer_with_overflow(b.CreateExtractValue(v, 1));
if (i.XO.Rc) {
// With cr0 update.
g.update_cr_with_cond(0, v0, b.getInt64(0), true);
}
return 0;
} else {
// No OE bit setting.
Value* v = b.CreateSub(b.getInt64(0), g.gpr_value(i.XO.RA));
g.update_gpr_value(i.XO.RT, v);
if (i.XO.Rc) {
// With cr0 update.
g.update_cr_with_cond(0, v, b.getInt64(0), true);
}
return 0;
}
}
XEDISASMR(subfx, 0x7C000050, XO )(InstrData& i, InstrDisasm& d) {

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "cpu/codegen/emit.h"
#include <xenia/cpu/codegen/emit.h>
#include <xenia/cpu/codegen/function_generator.h>
#include <xenia/cpu/ppc/state.h>

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "cpu/codegen/emit.h"
#include <xenia/cpu/codegen/emit.h>
#include <xenia/cpu/codegen/function_generator.h>
@@ -173,7 +173,28 @@ XEEMITTER(fcmpo, 0xFC000040, X )(FunctionGenerator& g, IRBuilder<>& b, I
return 1;
}
XEDISASMR(fcmpu, 0xFC000000, X )(InstrData& i, InstrDisasm& d) {
d.Init("fcmpu", "Floating Compare Unordered",
(i.XO.OE ? InstrDisasm::kOE : 0) | (i.XO.Rc ? InstrDisasm::kRc : 0));
d.AddRegOperand(InstrRegister::kGPR, i.XO.RT, InstrRegister::kWrite);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RA, InstrRegister::kRead);
d.AddRegOperand(InstrRegister::kGPR, i.XO.RB, InstrRegister::kRead);
return d.Finish();
}
XEEMITTER(fcmpu, 0xFC000000, X )(FunctionGenerator& g, IRBuilder<>& b, InstrData& i) {
// if (FRA) is a NaN or (FRB) is a NaN then
// c <- 0b0001
// else if (FRA) < (FRB) then
// c <- 0b1000
// else if (FRA) > (FRB) then
// c <- 0b0100
// else {
// c <- 0b0010
// }
// FPCC <- c
// CR[4*BF:4*BF+3] <- c
// if (FRA) is an SNaN or (FRB) is an SNaN then
// VXSNAN <- 1
XEINSTRNOTIMPLEMENTED();
return 1;
}

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "cpu/codegen/emit.h"
#include <xenia/cpu/codegen/emit.h>
#include <xenia/cpu/codegen/function_generator.h>

View File

@@ -11,10 +11,9 @@
#include <llvm/IR/Intrinsics.h>
#include <xenia/cpu/cpu-private.h>
#include <xenia/cpu/ppc/state.h>
#include "cpu/cpu-private.h"
using namespace llvm;
using namespace xe::cpu::codegen;

View File

@@ -0,0 +1,144 @@
/**
******************************************************************************
* 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_CODEGEN_FUNCTION_GENERATOR_H_
#define XENIA_CPU_CODEGEN_FUNCTION_GENERATOR_H_
#include <llvm/IR/Attributes.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <xenia/cpu/sdb.h>
#include <xenia/cpu/ppc/instr.h>
namespace xe {
namespace cpu {
namespace codegen {
class FunctionGenerator {
public:
FunctionGenerator(
xe_memory_ref memory, sdb::SymbolDatabase* sdb, sdb::FunctionSymbol* fn,
llvm::LLVMContext* context, llvm::Module* gen_module,
llvm::Function* gen_fn);
~FunctionGenerator();
sdb::SymbolDatabase* sdb();
sdb::FunctionSymbol* fn();
llvm::LLVMContext* context();
llvm::Module* gen_module();
llvm::Function* gen_fn();
sdb::FunctionBlock* fn_block();
void PushInsertPoint();
void PopInsertPoint();
void GenerateBasicBlocks();
llvm::BasicBlock* GetBasicBlock(uint32_t address);
llvm::BasicBlock* GetNextBasicBlock();
llvm::BasicBlock* GetReturnBasicBlock();
llvm::Function* GetFunction(sdb::FunctionSymbol* fn);
int GenerateIndirectionBranch(uint32_t cia, llvm::Value* target,
bool lk, bool likely_local);
llvm::Value* LoadStateValue(uint32_t offset, llvm::Type* type,
const char* name = "");
void StoreStateValue(uint32_t offset, llvm::Type* type, llvm::Value* value);
llvm::Value* cia_value();
llvm::Value* SetupLocal(llvm::Type* type, const char* name);
void FillRegisters();
void SpillRegisters();
llvm::Value* xer_value();
void update_xer_value(llvm::Value* value);
void update_xer_with_overflow(llvm::Value* value);
void update_xer_with_carry(llvm::Value* value);
void update_xer_with_overflow_and_carry(llvm::Value* value);
llvm::Value* lr_value();
void update_lr_value(llvm::Value* value);
llvm::Value* ctr_value();
void update_ctr_value(llvm::Value* value);
llvm::Value* cr_value(uint32_t n);
void update_cr_value(uint32_t n, llvm::Value* value);
void update_cr_with_cond(uint32_t n, llvm::Value* lhs, llvm::Value* rhs,
bool is_signed);
llvm::Value* gpr_value(uint32_t n);
void update_gpr_value(uint32_t n, llvm::Value* value);
llvm::Value* fpr_value(uint32_t n);
void update_fpr_value(uint32_t n, llvm::Value* value);
llvm::Value* GetMembase();
llvm::Value* GetMemoryAddress(uint32_t cia, llvm::Value* addr);
llvm::Value* ReadMemory(
uint32_t cia, llvm::Value* addr, uint32_t size, bool acquire = false);
void WriteMemory(
uint32_t cia, llvm::Value* addr, uint32_t size, llvm::Value* value,
bool release = false);
private:
void GenerateSharedBlocks();
int PrepareBasicBlock(sdb::FunctionBlock* block);
void GenerateBasicBlock(sdb::FunctionBlock* block);
void SetupLocals();
xe_memory_ref memory_;
sdb::SymbolDatabase* sdb_;
sdb::FunctionSymbol* fn_;
llvm::LLVMContext* context_;
llvm::Module* gen_module_;
llvm::Function* gen_fn_;
sdb::FunctionBlock* fn_block_;
llvm::BasicBlock* return_block_;
llvm::BasicBlock* internal_indirection_block_;
llvm::BasicBlock* external_indirection_block_;
llvm::BasicBlock* bb_;
llvm::IRBuilder<>* builder_;
std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock::iterator> >
insert_points_;
std::map<uint32_t, llvm::BasicBlock*> bbs_;
// Address of the instruction being generated.
uint32_t cia_;
ppc::InstrAccessBits access_bits_;
struct {
llvm::Value* indirection_target;
llvm::Value* indirection_cia;
llvm::Value* xer;
llvm::Value* lr;
llvm::Value* ctr;
llvm::Value* cr[8];
llvm::Value* gpr[32];
llvm::Value* fpr[32];
} locals_;
};
} // namespace codegen
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_CODEGEN_FUNCTION_GENERATOR_H_

View File

@@ -24,11 +24,10 @@
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <xenia/cpu/cpu-private.h>
#include <xenia/cpu/ppc.h>
#include <xenia/cpu/codegen/function_generator.h>
#include "cpu/cpu-private.h"
using namespace llvm;
using namespace xe;

View File

@@ -0,0 +1,91 @@
/**
******************************************************************************
* 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_CODEGEN_MODULE_GENERATOR_H_
#define XENIA_CPU_CODEGEN_MODULE_GENERATOR_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/cpu/sdb.h>
#include <xenia/core/memory.h>
#include <xenia/kernel/export.h>
namespace llvm {
class DIBuilder;
class ExecutionEngine;
class Function;
class FunctionType;
class LLVMContext;
class Module;
class MDNode;
}
namespace xe {
namespace cpu {
namespace codegen {
class ModuleGenerator {
public:
ModuleGenerator(
xe_memory_ref memory, kernel::ExportResolver* export_resolver,
const char* module_name, const char* module_path,
sdb::SymbolDatabase* sdb,
llvm::LLVMContext* context, llvm::Module* gen_module,
llvm::ExecutionEngine* engine);
~ModuleGenerator();
int Generate();
void AddFunctionsToMap(
std::tr1::unordered_map<uint32_t, llvm::Function*>& map);
private:
class CodegenFunction {
public:
sdb::FunctionSymbol* symbol;
llvm::FunctionType* function_type;
llvm::Function* function;
};
CodegenFunction* GetCodegenFunction(uint32_t address);
void AddImports();
llvm::Function* CreateFunctionDefinition(const char* name);
void AddMissingImport(sdb::FunctionSymbol* fn);
void AddPresentImport(sdb::FunctionSymbol* fn);
void PrepareFunction(sdb::FunctionSymbol* fn);
void BuildFunction(CodegenFunction* cgf);
void OptimizeFunction(llvm::Module* m, llvm::Function* fn);
xe_memory_ref memory_;
kernel::ExportResolver* export_resolver_;
char* module_name_;
char* module_path_;
sdb::SymbolDatabase* sdb_;
llvm::LLVMContext* context_;
llvm::Module* gen_module_;
llvm::ExecutionEngine* engine_;
llvm::DIBuilder* di_builder_;
llvm::MDNode* cu_;
std::map<uint32_t, CodegenFunction*> functions_;
};
} // namespace codegen
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_CODEGEN_MODULE_GENERATOR_H_

View File

@@ -1,11 +1,14 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'emit.h',
'emit_alu.cc',
'emit_control.cc',
'emit_fpu.cc',
'emit_memory.cc',
'function_generator.cc',
'function_generator.h',
'module_generator.cc',
'module_generator.h',
],
}

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "cpu/cpu-private.h"
#include <xenia/cpu/cpu-private.h>
// Tracing:

15
src/xenia/cpu/cpu.h Normal file
View File

@@ -0,0 +1,15 @@
/**
******************************************************************************
* 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_CPU_H_
#define XENIA_CPU_CPU_H_
#include <xenia/cpu/processor.h>
#endif // XENIA_CPU_CPU_H_

View File

@@ -28,14 +28,13 @@
#include <llvm/Transforms/IPO.h>
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <xenia/cpu/codegen/module_generator.h>
#include <xenia/cpu/cpu-private.h>
#include <xenia/cpu/llvm_exports.h>
#include <xenia/cpu/sdb.h>
#include <xenia/cpu/codegen/module_generator.h>
#include <xenia/cpu/ppc/instr.h>
#include <xenia/cpu/ppc/state.h>
#include "cpu/cpu-private.h"
#include "cpu/llvm_exports.h"
#include "cpu/xethunk/xethunk.h"
#include <xenia/cpu/xethunk/xethunk.h>
using namespace llvm;
@@ -107,7 +106,7 @@ int ExecModule::Prepare() {
PassManagerBuilder pmb;
// TODO(benvanik): embed the bc file into the emulator.
const char *thunk_path = "src/cpu/xethunk/xethunk.bc";
const char *thunk_path = "src/xenia/cpu/xethunk/xethunk.bc";
// Calculate a cache path based on the module, the CPU version, and other
// bits.

View File

@@ -0,0 +1,83 @@
/**
******************************************************************************
* 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_USERMODULE_H_
#define XENIA_CPU_USERMODULE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/cpu/sdb.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/xex2.h>
namespace llvm {
class ExecutionEngine;
class Function;
class LLVMContext;
class Module;
}
namespace xe {
namespace cpu {
namespace codegen {
class ModuleGenerator;
}
}
}
namespace xe {
namespace cpu {
typedef std::tr1::unordered_map<uint32_t, llvm::Function*> FunctionMap;
class ExecModule {
public:
ExecModule(
xe_memory_ref memory, shared_ptr<kernel::ExportResolver> export_resolver,
const char* module_name, const char* module_path,
shared_ptr<llvm::ExecutionEngine>& engine);
~ExecModule();
int PrepareXex(xe_xex2_ref xex);
int PrepareRawBinary(uint32_t start_address, uint32_t end_address);
void AddFunctionsToMap(FunctionMap& map);
void Dump();
private:
int Prepare();
int InjectGlobals();
int Init();
int Uninit();
xe_memory_ref memory_;
shared_ptr<kernel::ExportResolver> export_resolver_;
char* module_name_;
char* module_path_;
shared_ptr<llvm::ExecutionEngine> engine_;
shared_ptr<sdb::SymbolDatabase> sdb_;
shared_ptr<llvm::LLVMContext> context_;
shared_ptr<llvm::Module> gen_module_;
auto_ptr<codegen::ModuleGenerator> codegen_;
FunctionMap fns_;
};
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_USERMODULE_H_

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "cpu/llvm_exports.h"
#include <xenia/cpu/llvm_exports.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Constants.h>

18
src/xenia/cpu/ppc.h Normal file
View 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_

View File

@@ -11,7 +11,7 @@
#include <sstream>
#include "cpu/ppc/instr_tables.h"
#include <xenia/cpu/ppc/instr_tables.h>
using namespace xe::cpu::ppc;

328
src/xenia/cpu/ppc/instr.h Normal file
View File

@@ -0,0 +1,328 @@
/**
******************************************************************************
* 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>
#include <string>
#include <vector>
namespace xe {
namespace cpu {
namespace ppc {
// TODO(benvanik): rename these
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;
class InstrType;
static inline int32_t XEEXTS16(uint32_t v) {
return (int32_t)((int16_t)v);
}
static inline int32_t XEEXTS26(uint32_t v) {
return v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v);
}
static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) {
// if mstart ≤ mstop then
// mask[mstart:mstop] = ones
// mask[all other bits] = zeros
// else
// mask[mstart:63] = ones
// mask[0:mstop] = ones
// mask[all other bits] = zeros
uint64_t value =
(UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1));
return mstart <= mstop ? value : ~value;
}
typedef struct {
InstrType* type;
uint32_t address;
union {
uint32_t code;
// kXEPPCInstrFormatI
struct {
uint32_t LK : 1;
uint32_t AA : 1;
uint32_t LI : 24;
uint32_t : 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 : 6;
} B;
// kXEPPCInstrFormatSC
// kXEPPCInstrFormatD
struct {
uint32_t DS : 16;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} D;
// kXEPPCInstrFormatDS
struct {
uint32_t : 2;
uint32_t DS : 14;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} DS;
// kXEPPCInstrFormatX
struct {
uint32_t Rc : 1;
uint32_t : 10;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} X;
// kXEPPCInstrFormatXL
struct {
uint32_t LK : 1;
uint32_t : 10;
uint32_t BB : 5;
uint32_t BI : 5;
uint32_t BO : 5;
uint32_t : 6;
} XL;
// kXEPPCInstrFormatXFX
struct {
uint32_t : 1;
uint32_t : 10;
uint32_t spr : 10;
uint32_t RT : 5;
uint32_t : 6;
} XFX;
// kXEPPCInstrFormatXFL
// kXEPPCInstrFormatXS
struct {
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t : 9;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} XS;
// kXEPPCInstrFormatXO
struct {
uint32_t Rc : 1;
uint32_t : 9;
uint32_t OE : 1;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} XO;
// kXEPPCInstrFormatA
// kXEPPCInstrFormatM
struct {
uint32_t Rc : 1;
uint32_t ME : 5;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} M;
// kXEPPCInstrFormatMD
struct {
uint32_t Rc : 1;
uint32_t SH5 : 1;
uint32_t : 3;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t SH : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} MD;
// kXEPPCInstrFormatMDS
struct {
uint32_t Rc : 1;
uint32_t : 4;
uint32_t MB5 : 1;
uint32_t MB : 5;
uint32_t RB : 5;
uint32_t RA : 5;
uint32_t RT : 5;
uint32_t : 6;
} MDS;
// kXEPPCInstrFormatVA
// kXEPPCInstrFormatVX
// kXEPPCInstrFormatVXR
};
} InstrData;
typedef struct {
enum RegisterSet {
kXER,
kLR,
kCTR,
kCR, // 0-7
kFPSCR,
kGPR, // 0-31
kFPR, // 0-31
kVMX, // 0-127
};
enum Access {
kRead = 1 << 0,
kWrite = 1 << 1,
kReadWrite = kRead | kWrite,
};
RegisterSet set;
uint32_t ordinal;
Access access;
} InstrRegister;
typedef struct {
enum OperandType {
kRegister,
kImmediate,
};
OperandType type;
union {
InstrRegister reg;
struct {
bool is_signed;
uint64_t value;
size_t width;
} imm;
};
char display[32];
} InstrOperand;
class InstrAccessBits {
public:
InstrAccessBits() : spr(0), cr(0), gpr(0), fpr(0) {}
// Bitmasks derived from the accesses to registers.
// Format is 2 bits for each register, even bits indicating reads and odds
// indicating writes.
uint64_t spr; // fpcsr/ctr/lr/xer
uint64_t cr; // cr7/6/5/4/3/2/1/0
uint64_t gpr; // r31-0
uint64_t fpr; // f31-0
void Clear();
void Extend(InstrAccessBits& other);
void MarkAccess(InstrRegister& reg);
void Dump(std::string& out_str);
};
class InstrDisasm {
public:
enum Flags {
kOE = 1 << 0,
kRc = 1 << 1,
kCA = 1 << 2,
kLR = 1 << 4,
};
char name[16];
char info[64];
std::vector<InstrOperand> operands;
std::vector<InstrRegister> special_registers;
InstrAccessBits access_bits;
void Init(std::string name, std::string info, uint32_t flags);
void AddLR(InstrRegister::Access access);
void AddCTR(InstrRegister::Access access);
void AddCR(uint32_t bf, InstrRegister::Access access);
void AddRegOperand(InstrRegister::RegisterSet set, uint32_t ordinal,
InstrRegister::Access access, std::string display = "");
void AddSImmOperand(uint64_t value, size_t width, std::string display = "");
void AddUImmOperand(uint64_t value, size_t width, std::string display = "");
int Finish();
void Dump(std::string& str, size_t pad = 8);
};
typedef int (*InstrDisassembleFn)(InstrData& i, InstrDisasm& d);
typedef void* InstrEmitFn;
class InstrType {
public:
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];
InstrDisassembleFn disassemble;
InstrEmitFn emit;
};
InstrType* GetInstrType(uint32_t code);
int RegisterInstrDisassemble(uint32_t code, InstrDisassembleFn disassemble);
int RegisterInstrEmit(uint32_t code, InstrEmitFn emit);
} // namespace ppc
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_PPC_INSTR_H_

View File

@@ -2,6 +2,9 @@
{
'sources': [
'instr.cc',
'instr.h',
'instr_tables.h',
'state.cc',
'state.h',
],
}

169
src/xenia/cpu/ppc/state.h Normal file
View File

@@ -0,0 +1,169 @@
/**
******************************************************************************
* 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_
/**
* NOTE: this file is included by xethunk and as such should have a *MINIMAL*
* set of dependencies!
*/
#include <stdint.h>
#ifdef XE_THUNK
#define XECACHEALIGN __attribute__ ((aligned(8)))
#define XECACHEALIGN64 __attribute__ ((aligned(64)))
#endif
// namespace FPRF {
// enum 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,
// };
// } // FPRF
#define kXEPPCRegLR 0xFFFF0001
#define kXEPPCRegCTR 0xFFFF0002
typedef struct XECACHEALIGN xe_float4 {
union {
struct {
float x;
float y;
float z;
float w;
};
float f4[4];
struct {
uint64_t low;
uint64_t high;
};
};
} xe_float4_t;
typedef struct XECACHEALIGN64 xe_ppc_state {
uint32_t cia; // Current PC (CIA)
uint32_t nia; // Next PC (NIA)
uint64_t xer; // XER register
uint64_t lr; // Link register
uint64_t ctr; // Count register
uint64_t r[32]; // General purpose registers
xe_float4_t v[128]; // VMX128 vector registers
double f[32]; // Floating-point registers
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;
struct {
uint8_t value :4;
} cr2;
struct {
uint8_t value :4;
} cr3;
struct {
uint8_t value :4;
} cr4;
struct {
uint8_t value :4;
} cr5;
struct {
uint8_t value :4;
} cr6;
struct {
uint8_t value :4;
} cr7;
} 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
// uint32_t get_fprf() {
// return fpscr.value & 0x000F8000;
// }
// void set_fprf(const uint32_t v) {
// fpscr.value = (fpscr.value & ~0x000F8000) | v;
// }
// Runtime-specific data pointer. Used on callbacks to get access to the
// current runtime and its data.
uint8_t* membase;
void* processor;
void* thread_state;
void* runtime;
void SetRegFromString(const char* name, const char* value);
bool CompareRegWithString(const char* name, const char* value,
char* out_value, size_t out_value_size);
} xe_ppc_state_t;
#endif // XENIA_CPU_PPC_STATE_H_

View File

@@ -18,7 +18,7 @@
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/TargetSelect.h>
#include "cpu/codegen/emit.h"
#include <xenia/cpu/codegen/emit.h>
using namespace llvm;

75
src/xenia/cpu/processor.h Normal file
View File

@@ -0,0 +1,75 @@
/**
******************************************************************************
* 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_PROCESSOR_H_
#define XENIA_CPU_PROCESSOR_H_
#include <xenia/core.h>
#include <vector>
#include <xenia/cpu/exec_module.h>
#include <xenia/cpu/thread_state.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/xex2.h>
namespace llvm {
class ExecutionEngine;
class Function;
}
namespace xe {
namespace cpu {
class Processor {
public:
Processor(xe_pal_ref pal, xe_memory_ref memory);
~Processor();
xe_pal_ref pal();
xe_memory_ref memory();
int Setup();
int LoadBinary(const xechar_t* path, uint32_t start_address,
shared_ptr<kernel::ExportResolver> export_resolver);
int PrepareModule(const char* name, const char* path, xe_xex2_ref xex,
shared_ptr<kernel::ExportResolver> export_resolver);
uint32_t CreateCallback(void (*callback)(void* data), void* data);
ThreadState* AllocThread(uint32_t stack_size, uint32_t thread_state_address);
void DeallocThread(ThreadState* thread_state);
int Execute(ThreadState* thread_state, uint32_t address);
uint64_t Execute(ThreadState* thread_state, uint32_t address, uint64_t arg0);
private:
llvm::Function* GetFunction(uint32_t address);
xe_pal_ref pal_;
xe_memory_ref memory_;
shared_ptr<llvm::ExecutionEngine> engine_;
auto_ptr<llvm::LLVMContext> dummy_context_;
std::vector<ExecModule*> modules_;
FunctionMap all_fns_;
};
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_PROCESSOR_H_

18
src/xenia/cpu/sdb.h Normal file
View 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_SDB_H_
#define XENIA_CPU_SDB_H_
#include <xenia/cpu/sdb/raw_symbol_database.h>
#include <xenia/cpu/sdb/symbol.h>
#include <xenia/cpu/sdb/symbol_database.h>
#include <xenia/cpu/sdb/xex_symbol_database.h>
#endif // XENIA_CPU_SDB_H_

View File

@@ -0,0 +1,42 @@
/**
******************************************************************************
* 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_SDB_RAW_SYMBOL_DATABASE_H_
#define XENIA_CPU_SDB_RAW_SYMBOL_DATABASE_H_
#include <xenia/cpu/sdb/symbol_database.h>
namespace xe {
namespace cpu {
namespace sdb {
class RawSymbolDatabase : public SymbolDatabase {
public:
RawSymbolDatabase(xe_memory_ref memory,
kernel::ExportResolver* export_resolver,
uint32_t start_address, uint32_t end_address);
virtual ~RawSymbolDatabase();
private:
virtual uint32_t GetEntryPoint();
virtual bool IsValueInTextRange(uint32_t value);
uint32_t start_address_;
uint32_t end_address_;
};
} // namespace sdb
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_SDB_RAW_SYMBOL_DATABASE_H_

View File

@@ -2,8 +2,12 @@
{
'sources': [
'raw_symbol_database.cc',
'raw_symbol_database.h',
'symbol.cc',
'symbol.h',
'symbol_database.cc',
'symbol_database.h',
'xex_symbol_database.cc',
'xex_symbol_database.h',
]
}

151
src/xenia/cpu/sdb/symbol.h Normal file
View File

@@ -0,0 +1,151 @@
/**
******************************************************************************
* 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_SDB_SYMBOL_H_
#define XENIA_CPU_SDB_SYMBOL_H_
#include <xenia/core.h>
#include <map>
#include <vector>
#include <xenia/kernel/export.h>
namespace xe {
namespace cpu {
namespace sdb {
class FunctionSymbol;
class VariableSymbol;
class FunctionCall {
public:
uint32_t address;
FunctionSymbol* source;
FunctionSymbol* target;
};
class VariableAccess {
public:
uint32_t address;
FunctionSymbol* source;
VariableSymbol* target;
};
class Symbol {
public:
enum SymbolType {
Function = 0,
Variable = 1,
ExceptionEntry = 2,
};
virtual ~Symbol();
SymbolType symbol_type;
const char* name();
void set_name(const char* value);
protected:
Symbol(SymbolType type);
char* name_;
};
class ExceptionEntrySymbol;
class FunctionBlock {
public:
enum TargetType {
kTargetUnknown = 0,
kTargetBlock = 1,
kTargetFunction = 2,
kTargetLR = 3,
kTargetCTR = 4,
kTargetNone = 5,
};
FunctionBlock();
uint32_t start_address;
uint32_t end_address;
std::vector<FunctionBlock*> incoming_blocks;
TargetType outgoing_type;
uint32_t outgoing_address;
union {
FunctionSymbol* outgoing_function;
FunctionBlock* outgoing_block;
};
};
class FunctionSymbol : public Symbol {
public:
enum FunctionType {
Unknown = 0,
Kernel = 1,
User = 2,
};
enum Flags {
kFlagSaveGprLr = 1 << 1,
kFlagRestGprLr = 1 << 2,
};
FunctionSymbol();
virtual ~FunctionSymbol();
FunctionBlock* GetBlock(uint32_t address);
FunctionBlock* SplitBlock(uint32_t address);
uint32_t start_address;
uint32_t end_address;
FunctionType type;
uint32_t flags;
kernel::KernelExport* kernel_export;
ExceptionEntrySymbol* ee;
std::vector<FunctionCall*> incoming_calls;
std::vector<FunctionCall*> outgoing_calls;
std::vector<VariableAccess*> variable_accesses;
std::map<uint32_t, FunctionBlock*> blocks;
};
class VariableSymbol : public Symbol {
public:
VariableSymbol();
virtual ~VariableSymbol();
uint32_t address;
kernel::KernelExport* kernel_export;
};
class ExceptionEntrySymbol : public Symbol {
public:
ExceptionEntrySymbol();
virtual ~ExceptionEntrySymbol() {}
uint32_t address;
FunctionSymbol* function;
};
} // namespace sdb
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_SDB_SYMBOL_H_

View File

@@ -0,0 +1,77 @@
/**
******************************************************************************
* 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_SDB_SYMBOL_DATABASE_H_
#define XENIA_CPU_SDB_SYMBOL_DATABASE_H_
#include <xenia/core.h>
#include <list>
#include <map>
#include <vector>
#include <xenia/kernel/export.h>
#include <xenia/cpu/sdb/symbol.h>
namespace xe {
namespace cpu {
namespace sdb {
class SymbolDatabase {
public:
SymbolDatabase(xe_memory_ref memory, kernel::ExportResolver* export_resolver);
virtual ~SymbolDatabase();
virtual int Analyze();
Symbol* GetSymbol(uint32_t address);
ExceptionEntrySymbol* GetOrInsertExceptionEntry(uint32_t address);
FunctionSymbol* GetOrInsertFunction(uint32_t address);
VariableSymbol* GetOrInsertVariable(uint32_t address);
FunctionSymbol* GetFunction(uint32_t address);
VariableSymbol* GetVariable(uint32_t address);
int GetAllVariables(std::vector<VariableSymbol*>& variables);
int GetAllFunctions(std::vector<FunctionSymbol*>& functions);
void ReadMap(const char* file_name);
void WriteMap(const char* file_name);
void Dump(FILE* file);
void DumpFunctionBlocks(FILE* file, FunctionSymbol* fn);
protected:
typedef std::map<uint32_t, Symbol*> SymbolMap;
typedef std::list<FunctionSymbol*> FunctionList;
int AnalyzeFunction(FunctionSymbol* fn);
int CompleteFunctionGraph(FunctionSymbol* fn);
bool FillHoles();
int FlushQueue();
bool IsRestGprLr(uint32_t addr);
virtual uint32_t GetEntryPoint() = 0;
virtual bool IsValueInTextRange(uint32_t value) = 0;
xe_memory_ref memory_;
kernel::ExportResolver* export_resolver_;
size_t function_count_;
size_t variable_count_;
SymbolMap symbols_;
FunctionList scan_queue_;
};
} // namespace sdb
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_SDB_SYMBOL_DATABASE_H_

View File

@@ -0,0 +1,49 @@
/**
******************************************************************************
* 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_SDB_XEX_SYMBOL_DATABASE_H_
#define XENIA_CPU_SDB_XEX_SYMBOL_DATABASE_H_
#include <xenia/cpu/sdb/symbol_database.h>
#include <xenia/kernel/xex2.h>
namespace xe {
namespace cpu {
namespace sdb {
class XexSymbolDatabase : public SymbolDatabase {
public:
XexSymbolDatabase(xe_memory_ref memory,
kernel::ExportResolver* export_resolver,
xe_xex2_ref xex);
virtual ~XexSymbolDatabase();
virtual int Analyze();
private:
int FindGplr();
int AddImports(const xe_xex2_import_library_t *library);
int AddMethodHints();
virtual uint32_t GetEntryPoint();
virtual bool IsValueInTextRange(uint32_t value);
xe_xex2_ref xex_;
};
} // namespace sdb
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_SDB_XEX_SYMBOL_DATABASE_H_

View File

@@ -1,11 +1,18 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'cpu-private.h',
'cpu.cc',
'cpu.h',
'exec_module.cc',
'exec_module.h',
'llvm_exports.cc',
'llvm_exports.h',
'ppc.h',
'processor.cc',
'processor.h',
'thread_state.cc',
'thread_state.h',
],
'includes': [

View File

@@ -0,0 +1,49 @@
/**
******************************************************************************
* 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_THREAD_STATE_H_
#define XENIA_CPU_THREAD_STATE_H_
#include <xenia/core.h>
#include <xenia/cpu/ppc.h>
namespace xe {
namespace cpu {
class Processor;
class ThreadState {
public:
ThreadState(Processor* processor,
uint32_t stack_size, uint32_t thread_state_address);
~ThreadState();
xe_ppc_state_t* ppc_state();
private:
uint32_t stack_size_;
uint32_t thread_state_address;
xe_memory_ref memory_;
uint32_t stack_address_;
uint32_t thread_state_address_;
xe_ppc_state_t ppc_state_;
};
} // namespace cpu
} // namespace xe
#endif // XENIA_CPU_THREAD_STATE_H_

44
src/xenia/dbg/client.h Normal file
View File

@@ -0,0 +1,44 @@
/**
******************************************************************************
* 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_KERNEL_DBG_CLIENT_H_
#define XENIA_KERNEL_DBG_CLIENT_H_
#include <xenia/common.h>
#include <xenia/core.h>
namespace xe {
namespace dbg {
class Debugger;
class Client {
public:
Client(Debugger* debugger);
virtual ~Client();
virtual int Setup() = 0;
void OnMessage(const uint8_t* data, size_t length);
void Write(uint8_t* buffer, size_t length);
virtual void Write(uint8_t** buffers, size_t* lengths, size_t count) = 0;
protected:
Debugger* debugger_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_CLIENT_H_

View File

@@ -0,0 +1,43 @@
/**
******************************************************************************
* 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_KERNEL_DBG_CONTENT_SOURCE_H_
#define XENIA_KERNEL_DBG_CONTENT_SOURCE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/dbg/client.h>
namespace xe {
namespace dbg {
class ContentSource {
public:
ContentSource(Debugger* debugger, uint32_t source_id);
virtual ~ContentSource();
uint32_t source_id();
virtual int Dispatch(Client* client, uint8_t type, uint32_t request_id,
const uint8_t* data, size_t length) = 0;
protected:
Debugger* debugger_;
uint32_t source_id_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_CONTENT_SOURCE_H_

View File

@@ -12,8 +12,7 @@
#include <gflags/gflags.h>
#include <xenia/dbg/content_source.h>
#include "dbg/ws_listener.h"
#include <xenia/dbg/ws_listener.h>
using namespace xe;

59
src/xenia/dbg/debugger.h Normal file
View File

@@ -0,0 +1,59 @@
/**
******************************************************************************
* 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_KERNEL_DBG_DEBUGGER_H_
#define XENIA_KERNEL_DBG_DEBUGGER_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <map>
#include <vector>
namespace xe {
namespace dbg {
class Client;
class ContentSource;
class Listener;
class Debugger {
public:
Debugger(xe_pal_ref pal);
virtual ~Debugger();
void RegisterContentSource(ContentSource* content_source);
int Startup();
void Broadcast(uint32_t source_id, const uint8_t* data, size_t length);
private:
void AddClient(Client* client);
void RemoveClient(Client* client);
int Dispatch(Client* client, const uint8_t* data, size_t length);
friend class Client;
private:
xe_pal_ref pal_;
auto_ptr<Listener> listener_;
std::vector<Client*> clients_;
std::map<uint32_t, ContentSource*> content_sources_;
};
} // namespace dbg
} // namespace xe
#endif // XENIA_KERNEL_DBG_DEBUGGER_H_

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "dbg/listener.h"
#include <xenia/dbg/listener.h>
using namespace xe;

View File

@@ -2,10 +2,16 @@
{
'sources': [
'client.cc',
'client.h',
'content_source.cc',
'content_source.h',
'debugger.cc',
'debugger.h',
'listener.cc',
'listener.h',
'ws_client.cc',
'ws_client.h',
'ws_listener.cc',
'ws_listener.h',
],
}

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "dbg/ws_client.h"
#include <xenia/dbg/ws_client.h>
#include <xenia/dbg/debugger.h>

View File

@@ -7,13 +7,13 @@
******************************************************************************
*/
#include "dbg/ws_listener.h"
#include <xenia/dbg/ws_listener.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include "dbg/ws_client.h"
#include <xenia/dbg/ws_client.h>
using namespace xe;

View File

@@ -13,7 +13,7 @@
#include <xenia/common.h>
#include <xenia/core.h>
#include "dbg/listener.h"
#include <xenia/dbg/listener.h>
namespace xe {

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include <xenia/gpu.h>
#include <xenia/gpu/gpu.h>
void do_gpu_stuff() {

18
src/xenia/gpu/gpu.h Normal file
View 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_GPU_GPU_H_
#define XENIA_GPU_GPU_H_
#include <xenia/common.h>
#include <xenia/core.h>
void do_gpu_stuff();
#endif // XENIA_GPU_GPU_H_

View File

@@ -2,5 +2,6 @@
{
'sources': [
'gpu.cc',
'gpu.h',
],
}

108
src/xenia/kernel/export.h Normal file
View File

@@ -0,0 +1,108 @@
/**
******************************************************************************
* 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_KERNEL_EXPORT_H_
#define XENIA_KERNEL_EXPORT_H_
#include <xenia/core.h>
#include <vector>
typedef struct xe_ppc_state xe_ppc_state_t;
namespace xe {
namespace kernel {
typedef void (*xe_kernel_export_impl_fn)();
typedef void (*xe_kernel_export_shim_fn)(xe_ppc_state_t*, void*);
class KernelExport {
public:
enum ExportType {
Function = 0,
Variable = 1,
};
uint32_t ordinal;
ExportType type;
uint32_t flags;
char signature[16];
char name[96];
bool is_implemented;
union {
// Variable data. Only valid when kXEKernelExportFlagVariable is set.
// This is an address in the client memory space that the variable can
// be found at.
uint32_t variable_ptr;
struct {
// Second argument passed to the shim function.
void* shim_data;
// Shimmed implementation.
// This is called directly from generated code.
// It should parse args, do fixups, and call the impl.
xe_kernel_export_shim_fn shim;
// Real function implementation.
xe_kernel_export_impl_fn impl;
} function_data;
};
};
#define XE_DECLARE_EXPORT(module, ordinal, name, signature, type, flags) \
{ \
ordinal, \
KernelExport::type, \
flags, \
#signature, \
#name, \
}
class ExportResolver {
public:
ExportResolver();
~ExportResolver();
void RegisterTable(const char* library_name, KernelExport* exports,
const size_t count);
KernelExport* GetExportByOrdinal(const char* library_name,
const uint32_t ordinal);
KernelExport* GetExportByName(const char* library_name, const char* name);
void SetVariableMapping(const char* library_name, const uint32_t ordinal,
uint32_t value);
void SetFunctionMapping(const char* library_name, const uint32_t ordinal,
void* shim_data, xe_kernel_export_shim_fn shim,
xe_kernel_export_impl_fn impl);
private:
class ExportTable {
public:
char name[32];
KernelExport* exports;
size_t count;
};
std::vector<ExportTable> tables_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_EXPORT_H_

View File

@@ -0,0 +1,45 @@
/**
******************************************************************************
* 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_KERNEL_FS_DEVICE_H_
#define XENIA_KERNEL_FS_DEVICE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/fs/entry.h>
namespace xe {
namespace kernel {
namespace fs {
class Device {
public:
Device(xe_pal_ref pal, const char* path);
virtual ~Device();
xe_pal_ref pal();
const char* path();
virtual Entry* ResolvePath(const char* path) = 0;
protected:
xe_pal_ref pal_;
char* path_;
};
} // namespace fs
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_FS_DEVICE_H_

View File

@@ -7,9 +7,9 @@
******************************************************************************
*/
#include "kernel/fs/devices/disc_image_device.h"
#include <xenia/kernel/fs/devices/disc_image_device.h>
#include "kernel/fs/gdfx.h"
#include <xenia/kernel/fs/gdfx.h>
using namespace xe;
@@ -46,7 +46,6 @@ public:
}
virtual ~DiscImageFileEntry() {
delete gdfx_entry_;
xe_mmap_release(mmap_);
}

View File

@@ -7,7 +7,7 @@
******************************************************************************
*/
#include "kernel/fs/devices/local_directory_device.h"
#include <xenia/kernel/fs/devices/local_directory_device.h>
using namespace xe;

View File

@@ -2,6 +2,8 @@
{
'sources': [
'disc_image_device.cc',
'disc_image_device.h',
'local_directory_device.cc',
'local_directory_device.h',
],
}

View File

@@ -0,0 +1,88 @@
/**
******************************************************************************
* 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_KERNEL_FS_ENTRY_H_
#define XENIA_KERNEL_FS_ENTRY_H_
#include <xenia/common.h>
#include <xenia/core.h>
namespace xe {
namespace kernel {
namespace fs {
class Device;
class Entry {
public:
enum Type {
kTypeFile,
kTypeDirectory,
};
Entry(Type type, Device* device, const char* path);
virtual ~Entry();
Type type();
Device* device();
const char* path();
const char* name();
private:
Type type_;
Device* device_;
char* path_;
char* name_;
};
class MemoryMapping {
public:
MemoryMapping(uint8_t* address, size_t length);
virtual ~MemoryMapping();
uint8_t* address();
size_t length();
private:
uint8_t* address_;
size_t length_;
};
class FileEntry : public Entry {
public:
FileEntry(Device* device, const char* path);
virtual ~FileEntry();
//virtual void Query() = 0;
virtual MemoryMapping* CreateMemoryMapping(
xe_file_mode file_mode, const size_t offset, const size_t length) = 0;
};
class DirectoryEntry : public Entry {
public:
DirectoryEntry(Device* device, const char* path);
virtual ~DirectoryEntry();
//virtual void Query() = 0;
};
} // namespace fs
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_FS_ENTRY_H_

View File

@@ -9,8 +9,8 @@
#include <xenia/kernel/fs/filesystem.h>
#include "kernel/fs/devices/disc_image_device.h"
#include "kernel/fs/devices/local_directory_device.h"
#include <xenia/kernel/fs/devices/disc_image_device.h>
#include <xenia/kernel/fs/devices/local_directory_device.h>
using namespace xe;

View File

@@ -0,0 +1,56 @@
/**
******************************************************************************
* 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_KERNEL_FS_FILESYSTEM_H_
#define XENIA_KERNEL_FS_FILESYSTEM_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <vector>
#include <xenia/kernel/fs/entry.h>
namespace xe {
namespace kernel {
namespace fs {
class Device;
class FileSystem {
public:
FileSystem(xe_pal_ref pal);
~FileSystem();
int RegisterDevice(const char* path, Device* device);
int RegisterLocalDirectoryDevice(const char* path,
const xechar_t* local_path);
int RegisterDiscImageDevice(const char* path, const xechar_t* local_path);
int CreateSymbolicLink(const char* path, const char* target);
int DeleteSymbolicLink(const char* path);
Entry* ResolvePath(const char* path);
private:
xe_pal_ref pal_;
std::vector<Device*> devices_;
std::tr1::unordered_map<std::string, std::string> symlinks_;
};
} // namespace fs
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_FS_FILESYSTEM_H_

View File

@@ -9,7 +9,7 @@
* - abgx360
*/
#include "kernel/fs/gdfx.h"
#include <xenia/kernel/fs/gdfx.h>
using namespace xe;
@@ -24,6 +24,10 @@ namespace {
}
GDFXEntry::GDFXEntry() :
attributes(0), offset(0), size(0) {
}
GDFXEntry::~GDFXEntry() {
for (std::vector<GDFXEntry*>::iterator it = children.begin();
it != children.end(); ++it) {
@@ -170,10 +174,8 @@ bool GDFX::ReadEntry(ParseState& state, const uint8_t* buffer,
entry->name.append(1, '\0');
entry->attributes = attributes;
// Add to parent (if we have one).
if (parent) {
parent->children.push_back(entry);
}
// Add to parent.
parent->children.push_back(entry);
if (attributes & GDFXEntry::kAttrFolder) {
// Folder.

View File

@@ -38,7 +38,7 @@ public:
kAttrNormal = 0x00000080,
};
GDFXEntry() {}
GDFXEntry();
~GDFXEntry();
GDFXEntry* GetChild(const char* name);

View File

@@ -2,9 +2,13 @@
{
'sources': [
'device.cc',
'device.h',
'entry.cc',
'entry.h',
'filesystem.cc',
'filesystem.h',
'gdfx.cc',
'gdfx.h',
],
'includes': [

15
src/xenia/kernel/kernel.h Normal file
View File

@@ -0,0 +1,15 @@
/**
******************************************************************************
* 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_KERNEL_KERNEL_H_
#define XENIA_KERNEL_KERNEL_H_
#include <xenia/kernel/runtime.h>
#endif // XENIA_KERNEL_KERNEL_H_

View File

@@ -0,0 +1,54 @@
/**
******************************************************************************
* 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_KERNEL_KERNEL_MODULE_H_
#define XENIA_KERNEL_KERNEL_MODULE_H_
#include <xenia/common.h>
#include <xenia/core.h>
#include <xenia/kernel/export.h>
#include <xenia/kernel/runtime.h>
namespace xe {
namespace kernel {
class Runtime;
class KernelModule {
public:
KernelModule(Runtime* runtime) {
runtime_ = runtime;
pal_ = runtime->pal();
memory_ = runtime->memory();
export_resolver_ = runtime->export_resolver();
}
virtual ~KernelModule() {
export_resolver_.reset();
xe_memory_release(memory_);
xe_pal_release(pal_);
}
protected:
Runtime* runtime_;
xe_pal_ref pal_;
xe_memory_ref memory_;
shared_ptr<ExportResolver> export_resolver_;
};
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_KERNEL_MODULE_H_

View File

@@ -10,7 +10,7 @@
#ifndef XENIA_KERNEL_MODULES_H_
#define XENIA_KERNEL_MODULES_H_
#include "kernel/modules/xam/xam_module.h"
#include "kernel/modules/xboxkrnl/module.h"
#include <xenia/kernel/modules/xam/xam_module.h>
#include <xenia/kernel/modules/xboxkrnl/module.h>
#endif // XENIA_KERNEL_MODULES_H_

View File

@@ -1,5 +1,9 @@
# Copyright 2013 Ben Vanik. All Rights Reserved.
{
'sources': [
'modules.h',
],
'includes': [
'xam/sources.gypi',
'xboxkrnl/sources.gypi',

Some files were not shown because too many files have changed in this diff Show More