mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Fixed compilation errors
Implemented converter_le_be
This commit is contained in:
parent
28aaa94022
commit
cdfef3bf9e
18 changed files with 248 additions and 184 deletions
|
@ -490,14 +490,14 @@ private:
|
|||
};
|
||||
|
||||
public:
|
||||
const T& ToBE() const
|
||||
const type& ToBE() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
type ToLE() const
|
||||
{
|
||||
return se_t<T, sizeof(T2)>::func(m_data);
|
||||
return se_t<type, sizeof(T2)>::func(m_data);
|
||||
}
|
||||
|
||||
void FromBE(const type& value)
|
||||
|
@ -507,7 +507,7 @@ public:
|
|||
|
||||
void FromLE(const type& value)
|
||||
{
|
||||
m_data = se_t<T, sizeof(T2)>::func(value);
|
||||
m_data = se_t<type, sizeof(T2)>::func(value);
|
||||
}
|
||||
|
||||
static be_t MakeFromLE(const type value)
|
||||
|
@ -533,14 +533,14 @@ public:
|
|||
return is_le_machine ? ToLE() : ToBE();
|
||||
}
|
||||
|
||||
be_t() = default;
|
||||
be_t(const be_t& value) = default;
|
||||
|
||||
be_t(type value)
|
||||
{
|
||||
m_data = se_t<T, sizeof(T2)>::func(value);
|
||||
}
|
||||
//be_t() = default;
|
||||
//be_t(const be_t& value) = default;
|
||||
|
||||
//be_t(type value)
|
||||
//{
|
||||
// m_data = se_t<type, sizeof(T2)>::func(value);
|
||||
//}
|
||||
|
||||
be_t& operator = (const be_t& value) = default;
|
||||
|
||||
be_t& operator = (type value)
|
||||
|
@ -558,7 +558,8 @@ public:
|
|||
template<typename T1>
|
||||
operator const be_t<T1>() const
|
||||
{
|
||||
return _convert<T1, T, ((sizeof(T1) > sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data);
|
||||
return be_t<T1>::make(value());
|
||||
//return _convert<T1, T, ((sizeof(T1) > sizeof(T)) ? 1 : (sizeof(T1) < sizeof(T) ? 2 : 0))>::func(m_data);
|
||||
}
|
||||
|
||||
template<typename T1> be_t& operator += (T1 right) { return *this = T(*this) + right; }
|
||||
|
@ -644,6 +645,8 @@ public:
|
|||
|
||||
//be_t<T, size> if need swap endianes, T otherwise
|
||||
typedef typename _be_type_selector< T, T2, value >::type type;
|
||||
|
||||
typedef typename _be_type_selector< T, T2, !is_be_t<T, T2>::value >::type forced_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -771,3 +774,51 @@ template<typename T> __forceinline static void Write64(T& f, const u64 data)
|
|||
{
|
||||
Write64LE(f, re64(data));
|
||||
}
|
||||
|
||||
template<typename Tto, typename Tfrom>
|
||||
struct convert_le_be_t
|
||||
{
|
||||
static Tto func(Tfrom&& value)
|
||||
{
|
||||
return (Tto)value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tt, typename Tt1, typename Tfrom>
|
||||
struct convert_le_be_t<be_t<Tt, Tt1>, Tfrom>
|
||||
{
|
||||
static be_t<Tt, Tt1> func(Tfrom&& value)
|
||||
{
|
||||
return be_t<Tt, Tt1>::make(value);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tt, typename Tt1, typename Tf, typename Tf1>
|
||||
struct convert_le_be_t<be_t<Tt, Tt1>, be_t<Tf, Tf1>>
|
||||
{
|
||||
static be_t<Tt, Tt1> func(be_t<Tf, Tf1>&& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tto, typename Tf, typename Tf1>
|
||||
struct convert_le_be_t<Tto, be_t<Tf, Tf1>>
|
||||
{
|
||||
static Tto func(be_t<Tf, Tf1>&& value)
|
||||
{
|
||||
return value.value();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Tto, typename Tfrom>
|
||||
__forceinline Tto convert_le_be(Tfrom&& value)
|
||||
{
|
||||
return convert_le_be_t<Tto, Tfrom>::func(value);
|
||||
}
|
||||
|
||||
template<typename Tto, typename Tfrom>
|
||||
__forceinline void convert_le_be(Tto& dst, Tfrom&& src)
|
||||
{
|
||||
dst = convert_le_be_t<Tto, Tfrom>::func(src)
|
||||
}
|
|
@ -228,13 +228,13 @@ public:
|
|||
m_call_stack.erase((res + 1).base(), m_call_stack.end());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//add a new entry otherwise
|
||||
CallStackItem new_item;
|
||||
|
||||
|
||||
new_item.branch_pc = pc;
|
||||
new_item.pc = PC;
|
||||
|
||||
|
||||
m_call_stack.push_back(new_item);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ public:
|
|||
|
||||
virtual std::string GetThreadName() const
|
||||
{
|
||||
return (GetFName() + fmt::Format("[0x%08llx]", PC));
|
||||
return (GetFName() + fmt::Format("[0x%08x]", PC));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -643,8 +643,8 @@ namespace PPU_instr
|
|||
{
|
||||
using namespace lists;
|
||||
|
||||
static auto LIS = std::bind(ADDIS, std::placeholders::_1, r0, std::placeholders::_2);
|
||||
static auto LI = std::bind(ADDI, std::placeholders::_1, r0, std::placeholders::_2);
|
||||
//static auto LIS = std::bind(ADDIS, std::placeholders::_1, r0, std::placeholders::_2);
|
||||
//static auto LI = std::bind(ADDI, std::placeholders::_1, r0, std::placeholders::_2);
|
||||
static auto NOP = std::bind(ORI, r0, r0, 0);
|
||||
static auto MR = std::bind(OR, std::placeholders::_1, std::placeholders::_2, std::placeholders::_2, false);
|
||||
static auto BLR = std::bind(BCLR, 0x10 | 0x04, 0, 0, 0);
|
||||
|
|
|
@ -4479,14 +4479,14 @@ void Compiler::SetXerSo(Value * so) {
|
|||
}
|
||||
|
||||
Value * Compiler::GetUsprg0() {
|
||||
auto usrpg0_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, USPRG0));
|
||||
auto usrpg0_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, USPRG));
|
||||
auto usprg0_i64_ptr = m_ir_builder->CreateBitCast(usrpg0_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
|
||||
return m_ir_builder->CreateAlignedLoad(usprg0_i64_ptr, 8);
|
||||
}
|
||||
|
||||
void Compiler::SetUsprg0(Value * val_x64) {
|
||||
auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty());
|
||||
auto usprg0_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, USPRG0));
|
||||
auto usprg0_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, USPRG));
|
||||
auto usprg0_i64_ptr = m_ir_builder->CreateBitCast(usprg0_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo());
|
||||
m_ir_builder->CreateAlignedStore(val_i64, usprg0_i64_ptr, 8);
|
||||
}
|
||||
|
@ -4776,7 +4776,7 @@ void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool
|
|||
val_else_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_else_i32);
|
||||
}
|
||||
|
||||
Call<void>("vm.write32", (void(*)(u64, u32))vm::write32, addr_i64, val_else_i32);
|
||||
Call<void>("vm.write32", (void(*)(u32, u32))vm::write32, addr_i64, val_else_i32);
|
||||
m_ir_builder->CreateBr(merge_bb);
|
||||
|
||||
m_ir_builder->SetInsertPoint(merge_bb);
|
||||
|
|
|
@ -88,8 +88,8 @@ void PPUThread::InitRegs()
|
|||
|
||||
GPR[1] = align(m_stack_addr + m_stack_size, 0x200) - 0x200;
|
||||
GPR[2] = rtoc;
|
||||
GPR[11] = entry;
|
||||
GPR[12] = Emu.GetMallocPageSize();
|
||||
//GPR[11] = entry;
|
||||
//GPR[12] = Emu.GetMallocPageSize();
|
||||
GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060;
|
||||
|
||||
LR = Emu.GetPPUThreadExit();
|
||||
|
@ -244,4 +244,48 @@ ppu_thread::ppu_thread(u32 entry, const std::string& name, u32 stack_size, u32 p
|
|||
thread->SetPrio(prio ? prio : Emu.GetInfo().GetProcParam().primary_prio);
|
||||
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
cpu_thread& ppu_thread::args(std::initializer_list<std::string> values)
|
||||
{
|
||||
if (!values.size())
|
||||
return *this;
|
||||
|
||||
assert(argc == 0);
|
||||
|
||||
envp.set(vm::alloc(align((u32)sizeof(*envp), stack_align), vm::main));
|
||||
*envp = 0;
|
||||
argv.set(vm::alloc(sizeof(*argv) * values.size(), vm::main));
|
||||
|
||||
for (auto &arg : values)
|
||||
{
|
||||
u32 arg_size = align(u32(arg.size() + 1), stack_align);
|
||||
u32 arg_addr = vm::alloc(arg_size, vm::main);
|
||||
|
||||
std::strcpy(vm::get_ptr<char>(arg_addr), arg.c_str());
|
||||
|
||||
argv[argc++] = arg_addr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
cpu_thread& ppu_thread::run()
|
||||
{
|
||||
thread->Run();
|
||||
|
||||
gpr(3, argc);
|
||||
gpr(4, argv.addr());
|
||||
gpr(5, envp.addr());
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ppu_thread& ppu_thread::gpr(uint index, u64 value)
|
||||
{
|
||||
assert(index < 32);
|
||||
|
||||
static_cast<PPUThread*>(thread)->GPR[index] = value;
|
||||
|
||||
return *this;
|
||||
}
|
|
@ -808,38 +808,7 @@ class ppu_thread : cpu_thread
|
|||
public:
|
||||
ppu_thread(u32 entry, const std::string& name = "", u32 stack_size = 0, u32 prio = 0);
|
||||
|
||||
cpu_thread& args(std::initializer_list<std::string> values) override
|
||||
{
|
||||
if (!values.size())
|
||||
return *this;
|
||||
|
||||
assert(argc == 0);
|
||||
|
||||
envp.set(vm::alloc(align((u32)sizeof(*envp), stack_align), vm::main));
|
||||
*envp = 0;
|
||||
argv.set(vm::alloc(sizeof(*argv) * values.size(), vm::main));
|
||||
|
||||
for (auto &arg : values)
|
||||
{
|
||||
u32 arg_size = align(u32(arg.size() + 1), stack_align);
|
||||
u32 arg_addr = vm::alloc(arg_size, vm::main);
|
||||
|
||||
std::strcpy(vm::get_ptr<char>(arg_addr), arg.c_str());
|
||||
|
||||
argv[argc++] = arg_addr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
cpu_thread& run() override
|
||||
{
|
||||
thread->Run();
|
||||
|
||||
static_cast<PPUThread*>(thread)->GPR[3] = argc;
|
||||
static_cast<PPUThread*>(thread)->GPR[4] = argv.addr();
|
||||
static_cast<PPUThread*>(thread)->GPR[5] = envp.addr();
|
||||
|
||||
return *this;
|
||||
}
|
||||
cpu_thread& args(std::initializer_list<std::string> values) override;
|
||||
cpu_thread& run() override;
|
||||
ppu_thread& gpr(uint index, u64 value);
|
||||
};
|
|
@ -14,7 +14,7 @@ namespace vm
|
|||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
void* const g_base_addr = ::mmap(nullptr, 0x100000000, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
void* const g_base_addr = mmap(nullptr, 0x100000000, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
#endif
|
||||
|
||||
bool check_addr(u32 addr)
|
||||
|
|
|
@ -43,24 +43,12 @@ namespace vm
|
|||
return (T*)((u8*)g_base_addr + addr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T* const get_ptr(u64 addr)
|
||||
{
|
||||
return get_ptr<T>((u32)addr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& get_ref(u32 addr)
|
||||
{
|
||||
return *get_ptr<T>(addr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T& get_ref(u64 addr)
|
||||
{
|
||||
return get_ref<T>((u32)addr);
|
||||
}
|
||||
|
||||
namespace ps3
|
||||
{
|
||||
void init();
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace vm
|
|||
template<typename AT2>
|
||||
operator const _ptr_base<T, lvl, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr = m_addr;
|
||||
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
|
||||
return (_ptr_base<T, lvl, AT2>&)addr;
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,12 @@ namespace vm
|
|||
return vm::get_ref<T>(m_addr);
|
||||
}
|
||||
|
||||
__forceinline T& operator [](AT index) const
|
||||
__forceinline T& operator [](typename remove_be_t<AT>::type index) const
|
||||
{
|
||||
return vm::get_ref<T>(m_addr + sizeof(AT)* index);
|
||||
}
|
||||
|
||||
__forceinline T& operator [](typename to_be_t<AT>::forced_type index) const
|
||||
{
|
||||
return vm::get_ref<T>(m_addr + sizeof(AT)* index);
|
||||
}
|
||||
|
@ -196,9 +201,10 @@ namespace vm
|
|||
return m_addr;
|
||||
}
|
||||
|
||||
void set(AT value)
|
||||
template<typename T>
|
||||
void set(T&& value)
|
||||
{
|
||||
m_addr = value;
|
||||
m_addr = convert_le_be<AT>(value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -212,7 +218,7 @@ namespace vm
|
|||
template<typename AT2>
|
||||
operator const _ptr_base<T, 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr = m_addr;
|
||||
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
|
||||
return (_ptr_base<T, 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
|
@ -270,14 +276,14 @@ namespace vm
|
|||
template<typename AT2>
|
||||
operator const _ptr_base<void, 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr = m_addr;
|
||||
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
|
||||
return (_ptr_base<void, 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
template<typename AT2>
|
||||
operator const _ptr_base<const void, 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr = m_addr;
|
||||
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
|
||||
return (_ptr_base<const void, 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
|
@ -330,7 +336,7 @@ namespace vm
|
|||
template<typename AT2>
|
||||
operator const _ptr_base<const void, 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr; addr = m_addr;
|
||||
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
|
||||
return (_ptr_base<const void, 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
|
@ -379,7 +385,7 @@ namespace vm
|
|||
template<typename AT2>
|
||||
operator const _ptr_base<RT(*)(T...), 1, AT2>() const
|
||||
{
|
||||
typename std::remove_const<AT2>::type addr = m_addr;
|
||||
typename std::remove_const<AT2>::type addr = convert_le_be<AT2>(m_addr);
|
||||
return (_ptr_base<RT(*)(T...), 1, AT2>&)addr;
|
||||
}
|
||||
|
||||
|
@ -390,7 +396,7 @@ namespace vm
|
|||
|
||||
operator const std::function<RT(T...)>() const
|
||||
{
|
||||
typename std::remove_const<AT>::type addr = m_addr;
|
||||
typename std::remove_const<AT>::type addr = convert_le_be<AT>(m_addr);
|
||||
return [addr](T... args) -> RT { return make(addr)(args...); };
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ void fix_import(Module* module, u32 func, u32 addr)
|
|||
|
||||
vm::ptr<u32>& ptr = (vm::ptr<u32>&)addr;
|
||||
|
||||
*ptr++ = LIS(11, func >> 16);
|
||||
*ptr++ = ADDIS(11, 0, func >> 16);
|
||||
*ptr++ = ORI(11, 11, func & 0xffff);
|
||||
*ptr++ = NOP();
|
||||
++ptr;
|
||||
|
|
|
@ -1691,7 +1691,7 @@ s64 cellSpursGetWorkloadFlag(vm::ptr<CellSpurs> spurs, vm::ptr<vm::bptr<CellSpur
|
|||
return CELL_SPURS_POLICY_MODULE_ERROR_ALIGN;
|
||||
}
|
||||
|
||||
flag->set(be_t<u32>::make(Memory.RealToVirtualAddr(&spurs->m.wklFlag)));
|
||||
flag->set(Memory.RealToVirtualAddr(&spurs->m.wklFlag));
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -290,7 +290,7 @@ s32 syncRwmInitialize(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buffer, u32 buffer
|
|||
}
|
||||
|
||||
// prx: zeroize first u16 and second u16, write buffer_size in second u32, write buffer_addr in second u64 and sync
|
||||
rwm->m_size = buffer_size;
|
||||
rwm->m_size = be_t<u32>::make(buffer_size);
|
||||
rwm->m_buffer = buffer;
|
||||
rwm->data.exchange({});
|
||||
return CELL_OK;
|
||||
|
@ -479,9 +479,9 @@ s32 syncQueueInitialize(vm::ptr<CellSyncQueue> queue, vm::ptr<u8> buffer, u32 si
|
|||
}
|
||||
|
||||
// prx: zeroize first u64, write size in third u32, write depth in fourth u32, write address in third u64 and sync
|
||||
queue->m_size = size;
|
||||
queue->m_depth = depth;
|
||||
queue->m_buffer = buffer;
|
||||
queue->m_size = be_t<u32>::make(size);
|
||||
queue->m_depth = be_t<u32>::make(depth);
|
||||
queue->m_buffer.set(buffer.addr());
|
||||
queue->data.exchange({});
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -855,7 +855,7 @@ void syncLFQueueInit(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u8> buffer, u32 siz
|
|||
{
|
||||
queue->pop1.write_relaxed({});
|
||||
queue->push1.write_relaxed({});
|
||||
queue->m_buffer.set(queue->m_buffer.addr() | be_t<u64>::make(1));
|
||||
queue->m_buffer.set(queue->m_buffer.addr() | 1);
|
||||
queue->m_bs[0] = -1;
|
||||
queue->m_bs[1] = -1;
|
||||
//m_bs[2]
|
||||
|
|
|
@ -15,7 +15,7 @@ s32 lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name_u64)
|
|||
|
||||
u32 id = sys_lwcond.GetNewId(new Lwcond(name_u64), TYPE_LWCOND);
|
||||
u32 addr = Memory.RealToVirtualAddr(&lwmutex);
|
||||
lwcond.lwmutex.set(be_t<u32>::make(addr));
|
||||
lwcond.lwmutex.set(addr);
|
||||
lwcond.lwcond_queue = id;
|
||||
|
||||
std::string name((const char*)&name_u64, 8);
|
||||
|
|
|
@ -90,7 +90,7 @@ struct sys_spu_segment
|
|||
|
||||
union
|
||||
{
|
||||
be_t<u32> addr; // address or fill value
|
||||
be_t<u32> addr; // address or fill value
|
||||
u64 pad;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -45,10 +45,10 @@ public:
|
|||
SetTLSData(0, 0, 0);
|
||||
memset(&proc_param, 0, sizeof(sys_process_param_info));
|
||||
|
||||
proc_param.malloc_pagesize = 0x100000;
|
||||
proc_param.sdk_version = 0x360001;
|
||||
proc_param.primary_stacksize = 0x100000;
|
||||
proc_param.primary_prio = 0x50;
|
||||
proc_param.malloc_pagesize = be_t<u32>::make(0x100000);
|
||||
proc_param.sdk_version = be_t<u32>::make(0x360001);
|
||||
proc_param.primary_stacksize = be_t<u32>::make(0x100000);
|
||||
proc_param.primary_prio = be_t<u32>::make(0x50);
|
||||
}
|
||||
|
||||
void SetTLSData(const u64 addr, const u64 filesz, const u64 memsz)
|
||||
|
|
|
@ -323,7 +323,7 @@ namespace loader
|
|||
ppu_thr_stop_data[1] = BLR();
|
||||
Emu.SetPPUThreadStop(ppu_thr_stop_data.addr());
|
||||
|
||||
//vm::write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE);
|
||||
vm::write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE);
|
||||
/*
|
||||
//TODO
|
||||
static const int branch_size = 6 * 4;
|
||||
|
@ -354,7 +354,10 @@ namespace loader
|
|||
make_branch(entry, m_ehdr.e_entry);
|
||||
*/
|
||||
|
||||
ppu_thread(m_ehdr.e_entry, "main_thread").args({ Emu.GetPath()/*, "-emu"*/ }).run();
|
||||
ppu_thread main_thread(m_ehdr.e_entry, "main_thread");
|
||||
|
||||
main_thread.args({ Emu.GetPath()/*, "-emu"*/ }).run();
|
||||
main_thread.gpr(11, m_ehdr.e_entry).gpr(12, Emu.GetMallocPageSize());
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
|
|
@ -33,15 +33,9 @@
|
|||
<Filter Include="Emu\HDD">
|
||||
<UniqueIdentifier>{28902cf4-4fa6-428b-ab94-6b410fd5077f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\Cell">
|
||||
<UniqueIdentifier>{13d20086-2188-425a-9856-0440fe6f79f2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\CPU">
|
||||
<UniqueIdentifier>{037247b4-0370-4193-a25d-bc9d075bf0a7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\ARMv7">
|
||||
<UniqueIdentifier>{93b1cff1-0158-4327-a437-e9abcac8d724}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\Audio">
|
||||
<UniqueIdentifier>{5a18e5b1-2632-4849-ba94-e7a2ea0b78fa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
|
@ -60,24 +54,33 @@
|
|||
<Filter Include="Utilities\SimpleIni">
|
||||
<UniqueIdentifier>{84c34dd1-4c49-4ecf-8ee2-4165c14f24be}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\RSX">
|
||||
<UniqueIdentifier>{fadb4b36-57af-4583-891d-d22ff369e266}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\RSX\Null">
|
||||
<UniqueIdentifier>{4adca4fa-b90f-4662-9eb0-1d29cf3cd2eb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\RSX\GL">
|
||||
<UniqueIdentifier>{6f1da5b2-52c5-416b-9b5c-b9897bc1b300}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\Io\Null">
|
||||
<UniqueIdentifier>{fcac6852-b45f-4cf2-afee-cf56bcea14e5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\SysCalls\currently_unused">
|
||||
<UniqueIdentifier>{ead7494f-a872-4b4d-a864-1a61c3b6012f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\ARMv7\Modules">
|
||||
<Filter Include="Emu\CPU\Cell">
|
||||
<UniqueIdentifier>{13d20086-2188-425a-9856-0440fe6f79f2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\CPU\ARMv7">
|
||||
<UniqueIdentifier>{93b1cff1-0158-4327-a437-e9abcac8d724}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\CPU\ARMv7\Modules">
|
||||
<UniqueIdentifier>{1d9e6fc4-9a79-4329-a8b5-081e24822aaa}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\GPU">
|
||||
<UniqueIdentifier>{6674e2ab-90cd-47de-a852-d21643ab18c2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\GPU\RSX">
|
||||
<UniqueIdentifier>{fadb4b36-57af-4583-891d-d22ff369e266}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\GPU\RSX\Null">
|
||||
<UniqueIdentifier>{4adca4fa-b90f-4662-9eb0-1d29cf3cd2eb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Emu\GPU\RSX\GL">
|
||||
<UniqueIdentifier>{6f1da5b2-52c5-416b-9b5c-b9897bc1b300}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Crypto\aes.cpp">
|
||||
|
@ -309,28 +312,28 @@
|
|||
<Filter>Emu\HDD</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\MFC.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPCDecoder.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPCThread.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPUThread.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\RawSPUThread.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\SPURecompilerCore.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\SPURSManager.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\SPUThread.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\CPU\CPUThread.cpp">
|
||||
<Filter>Emu\CPU</Filter>
|
||||
|
@ -339,7 +342,7 @@
|
|||
<Filter>Emu\CPU</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\ARMv7Thread.cpp">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Audio\AudioManager.cpp">
|
||||
<Filter>Emu\Audio</Filter>
|
||||
|
@ -555,37 +558,37 @@
|
|||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\GLProgram.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\GLProgramBuffer.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\GLVertexProgram.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\OpenGL.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\GLBuffers.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\GLFragmentProgram.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GL\GLGSRender.cpp">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GSManager.cpp">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\GSRender.cpp">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\RSXTexture.cpp">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\RSXThread.cpp">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\SysCalls\lv2\sys_event_flag.cpp">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
|
@ -624,31 +627,31 @@
|
|||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPULLVMRecompiler.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\Cell\PPULLVMRecompilerTests.cpp">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\ARMv7Interpreter.cpp">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\ARMv7DisAsm.cpp">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\PSVFuncList.cpp">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\Modules\sceLibc.cpp">
|
||||
<Filter>Emu\ARMv7\Modules</Filter>
|
||||
<Filter>Emu\CPU\ARMv7\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\Modules\sceLibstdcxx.cpp">
|
||||
<Filter>Emu\ARMv7\Modules</Filter>
|
||||
<Filter>Emu\CPU\ARMv7\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\Modules\sceLibKernel.cpp">
|
||||
<Filter>Emu\ARMv7\Modules</Filter>
|
||||
<Filter>Emu\CPU\ARMv7\Modules</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\ARMv7\Modules\sceLibm.cpp">
|
||||
<Filter>Emu\ARMv7\Modules</Filter>
|
||||
<Filter>Emu\CPU\ARMv7\Modules</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -878,64 +881,64 @@
|
|||
<Filter>Emu\HDD</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\MFC.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPCDecoder.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPCDisAsm.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPCInstrTable.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPCThread.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUDecoder.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUDisAsm.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUInstrTable.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUInterpreter.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUOpcodes.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPUThread.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\RawSPUThread.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPUDecoder.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPUDisAsm.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPUInstrTable.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPUInterpreter.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPUOpcodes.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPURecompiler.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPURSManager.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\SPUThread.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\CPU\CPUDecoder.h">
|
||||
<Filter>Emu\CPU</Filter>
|
||||
|
@ -953,19 +956,19 @@
|
|||
<Filter>Emu\CPU</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Decoder.h">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7DisAsm.h">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Interpreter.h">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Opcodes.h">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\ARMv7Thread.h">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Audio\AudioDumper.h">
|
||||
<Filter>Emu\Audio</Filter>
|
||||
|
@ -1121,58 +1124,58 @@
|
|||
<Filter>Emu\SysCalls</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\Null\NullGSRender.h">
|
||||
<Filter>Emu\RSX\Null</Filter>
|
||||
<Filter>Emu\GPU\RSX\Null</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLGSRender.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLProcTable.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLProgram.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLProgramBuffer.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLShaderParam.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLVertexProgram.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\OpenGL.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLBuffers.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GL\GLFragmentProgram.h">
|
||||
<Filter>Emu\RSX\GL</Filter>
|
||||
<Filter>Emu\GPU\RSX\GL</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GSManager.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GSRender.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\RSXFragmentProgram.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\RSXTexture.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\RSXThread.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\RSXVertexProgram.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\sysutil_video.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\GCM.h">
|
||||
<Filter>Emu\RSX</Filter>
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\SysCalls\lv2\sys_event_flag.h">
|
||||
<Filter>Emu\SysCalls\lv2</Filter>
|
||||
|
@ -1253,10 +1256,10 @@
|
|||
<Filter>Emu\SysCalls\Modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\Cell\PPULLVMRecompiler.h">
|
||||
<Filter>Emu\Cell</Filter>
|
||||
<Filter>Emu\CPU\Cell</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\ARMv7\PSVFuncList.h">
|
||||
<Filter>Emu\ARMv7</Filter>
|
||||
<Filter>Emu\CPU\ARMv7</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Reference in a new issue