mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-20 22:05:12 +00:00
ARMv7: argc, argv setting, LDRSB_IMM, bugfixes
This commit is contained in:
parent
8a945a1a52
commit
e5dd03dbcb
14 changed files with 184 additions and 98 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include <unordered_map>
|
||||
#include "Utilities/Log.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "ARMv7Thread.h"
|
||||
#include "ARMv7Interpreter.h"
|
||||
#include "ARMv7Opcodes.h"
|
||||
|
|
@ -1262,7 +1263,7 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump)
|
|||
addr += 16;
|
||||
}
|
||||
|
||||
LOG_NOTICE(ARMv7, "armv7_decoder_initialize() finished, g_opct.size() = %lld", g_opct.size());
|
||||
LOG_NOTICE(ARMv7, "armv7_decoder_initialize() finished, g_opct.size() = %lld", (u64)g_opct.size());
|
||||
}
|
||||
|
||||
u32 ARMv7Decoder::DecodeMemory(const u32 address)
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ namespace ARMv7_instrs
|
|||
|
||||
template<typename T> T AddWithCarry(T x, T y, bool carry_in, bool& carry_out, bool& overflow)
|
||||
{
|
||||
const T sign_mask = (T)1 << (sizeof(T) - 1);
|
||||
const T sign_mask = (T)1 << (sizeof(T) * 8 - 1);
|
||||
|
||||
T result = x + y;
|
||||
carry_out = ((x & y) | ((x ^ y) & ~result)) & sign_mask;
|
||||
|
|
@ -823,6 +823,7 @@ void ARMv7_instrs::B(ARMv7Context& context, const ARMv7Code code, const ARMv7_en
|
|||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
//LOG_NOTICE(ARMv7, "Branch to 0x%x (cond=0x%x)", context.thread.PC + jump, cond);
|
||||
context.thread.SetBranch(context.thread.PC + jump);
|
||||
}
|
||||
}
|
||||
|
|
@ -1174,6 +1175,7 @@ void ARMv7_instrs::CMP_REG(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
}
|
||||
case T3:
|
||||
{
|
||||
cond = context.ITSTATE.advance();
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
m = (code.data & 0xf);
|
||||
shift_t = DecodeImmShift((code.data & 0x30) >> 4, (code.data & 0x7000) >> 10 | (code.data & 0xc0) >> 6, &shift_n);
|
||||
|
|
@ -1187,13 +1189,17 @@ void ARMv7_instrs::CMP_REG(ARMv7Context& context, const ARMv7Code code, const AR
|
|||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
const u32 m_value = context.read_gpr(m);
|
||||
const u32 n_value = context.read_gpr(n);
|
||||
bool carry, overflow;
|
||||
const u32 shifted = Shift(context.read_gpr(m), shift_t, shift_n, true);
|
||||
const u32 res = AddWithCarry(context.read_gpr(n), ~shifted, true, carry, overflow);
|
||||
const u32 shifted = Shift(m_value, shift_t, shift_n, true);
|
||||
const u32 res = AddWithCarry(n_value, ~shifted, true, carry, overflow);
|
||||
context.APSR.N = res >> 31;
|
||||
context.APSR.Z = res == 0;
|
||||
context.APSR.C = carry;
|
||||
context.APSR.V = overflow;
|
||||
|
||||
//LOG_NOTICE(ARMv7, "CMP: r%d=0x%08x <> r%d=0x%08x, shifted=0x%08x, res=0x%08x", n, n_value, m, m_value, shifted, res);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1619,11 +1625,60 @@ void ARMv7_instrs::LDRH_REG(ARMv7Context& context, const ARMv7Code code, const A
|
|||
|
||||
void ARMv7_instrs::LDRSB_IMM(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond, t, n, imm32;
|
||||
bool index, add, wback;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
cond = context.ITSTATE.advance();
|
||||
t = (code.data & 0xf000) >> 12;
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
imm32 = (code.data & 0xfff);
|
||||
index = true;
|
||||
add = true;
|
||||
wback = false;
|
||||
|
||||
reject(t == 15, "PLI");
|
||||
reject(n == 15, "LDRSB (literal)");
|
||||
reject(t == 13, "UNPREDICTABLE");
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
cond = context.ITSTATE.advance();
|
||||
t = (code.data & 0xf000) >> 12;
|
||||
n = (code.data & 0xf0000) >> 16;
|
||||
imm32 = (code.data & 0xff);
|
||||
index = (code.data & 0x400);
|
||||
add = (code.data & 0x200);
|
||||
wback = (code.data & 0x100);
|
||||
|
||||
reject(t == 15 && index && !add && !wback, "PLI");
|
||||
reject(n == 15, "LDRSB (literal)");
|
||||
reject(index && add && !wback, "LDRSBT");
|
||||
reject(!index && !wback, "UNDEFINED");
|
||||
reject(t == 13 || t == 15 || (wback && n == t), "UNPREDICTABLE");
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(context, cond))
|
||||
{
|
||||
const u32 offset_addr = add ? context.read_gpr(n) + imm32 : context.read_gpr(n) - imm32;
|
||||
const u32 addr = index ? offset_addr : context.read_gpr(n);
|
||||
const s8 value = vm::psv::read8(addr);
|
||||
|
||||
context.write_gpr(t, value); // sign-extend
|
||||
|
||||
if (wback)
|
||||
{
|
||||
context.write_gpr(n, offset_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7_instrs::LDRSB_LIT(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type)
|
||||
|
|
|
|||
|
|
@ -120,10 +120,19 @@ void ARMv7Thread::InitRegs()
|
|||
|
||||
void ARMv7Thread::InitStack()
|
||||
{
|
||||
if(!m_stack_addr)
|
||||
if (!m_stack_addr)
|
||||
{
|
||||
m_stack_size = 0x10000;
|
||||
m_stack_addr = (u32)Memory.Alloc(0x10000, 1);
|
||||
assert(m_stack_size);
|
||||
m_stack_addr = vm::cast(Memory.Alloc(m_stack_size, 4096));
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7Thread::CloseStack()
|
||||
{
|
||||
if (m_stack_addr)
|
||||
{
|
||||
Memory.Free(m_stack_addr);
|
||||
m_stack_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +227,7 @@ void ARMv7Thread::FastStop()
|
|||
m_status = Stopped;
|
||||
}
|
||||
|
||||
arm7_thread::arm7_thread(u32 entry, const std::string& name, u32 stack_size, u32 prio)
|
||||
armv7_thread::armv7_thread(u32 entry, const std::string& name, u32 stack_size, u32 prio)
|
||||
{
|
||||
thread = &Emu.GetCPU().AddThread(CPU_THREAD_ARMv7);
|
||||
|
||||
|
|
@ -229,3 +238,47 @@ arm7_thread::arm7_thread(u32 entry, const std::string& name, u32 stack_size, u32
|
|||
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
cpu_thread& armv7_thread::args(std::initializer_list<std::string> values)
|
||||
{
|
||||
assert(argc == 0);
|
||||
|
||||
if (!values.size())
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::vector<char> argv_data;
|
||||
u32 argv_size = 0;
|
||||
|
||||
for (auto& arg : values)
|
||||
{
|
||||
const u32 arg_size = vm::cast(arg.size(), "arg.size()"); // get arg size
|
||||
|
||||
for (char c : arg)
|
||||
{
|
||||
argv_data.push_back(c); // append characters
|
||||
}
|
||||
|
||||
argv_data.push_back('\0'); // append null terminator
|
||||
|
||||
argv_size += arg_size + 1;
|
||||
argc++;
|
||||
}
|
||||
|
||||
argv = vm::cast(Memory.PSV.RAM.AllocAlign(argv_size, 4096)); // allocate arg list
|
||||
memcpy(vm::get_ptr(argv), argv_data.data(), argv_size); // copy arg list
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
cpu_thread& armv7_thread::run()
|
||||
{
|
||||
thread->Run();
|
||||
|
||||
// set arguments
|
||||
static_cast<ARMv7Thread*>(thread)->context.GPR[0] = argc;
|
||||
static_cast<ARMv7Thread*>(thread)->context.GPR[1] = argv;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,19 @@
|
|||
#pragma once
|
||||
#include "Emu/CPU/CPUThread.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "ARMv7Context.h"
|
||||
|
||||
class ARMv7Thread : public CPUThread
|
||||
{
|
||||
public:
|
||||
ARMv7Context context;
|
||||
//u32 m_arg;
|
||||
//u8 m_last_instr_size;
|
||||
//const char* m_last_instr_name;
|
||||
|
||||
ARMv7Thread();
|
||||
~ARMv7Thread();
|
||||
|
||||
//void update_code(const u32 address)
|
||||
//{
|
||||
// code.code0 = vm::psv::read16(address & ~1);
|
||||
// code.code1 = vm::psv::read16(address + 2 & ~1);
|
||||
// m_arg = address & 0x1 ? code.code1 << 16 | code.code0 : code.data;
|
||||
//}
|
||||
|
||||
public:
|
||||
virtual void InitRegs();
|
||||
virtual void InitStack();
|
||||
virtual void CloseStack();
|
||||
u32 GetStackArg(u32 pos);
|
||||
void FastCall(u32 addr);
|
||||
void FastStop();
|
||||
|
|
@ -42,48 +32,16 @@ protected:
|
|||
|
||||
virtual void DoCode();
|
||||
};
|
||||
class arm7_thread : cpu_thread
|
||||
|
||||
class armv7_thread : cpu_thread
|
||||
{
|
||||
static const u32 stack_align = 0x10;
|
||||
vm::ptr<u64> argv;
|
||||
u32 argv;
|
||||
u32 argc;
|
||||
vm::ptr<u64> envp;
|
||||
|
||||
public:
|
||||
arm7_thread(u32 entry, const std::string& name = "", u32 stack_size = 0, u32 prio = 0);
|
||||
armv7_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;
|
||||
cpu_thread& args(std::initializer_list<std::string> values) override;
|
||||
|
||||
//assert(argc == 0);
|
||||
|
||||
//envp.set(vm::alloc((u32)sizeof(envp), stack_align, vm::main));
|
||||
//*envp = 0;
|
||||
//argv.set(vm::alloc(u32(sizeof(argv)* values.size()), stack_align, vm::main));
|
||||
|
||||
for (auto &arg : values)
|
||||
{
|
||||
//u32 arg_size = align(u32(arg.size() + 1), stack_align);
|
||||
//u32 arg_addr = vm::alloc(arg_size, stack_align, 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<ARMv7Thread*>(thread)->GPR[0] = argc;
|
||||
//static_cast<ARMv7Thread*>(thread)->GPR[1] = argv.addr();
|
||||
//static_cast<ARMv7Thread*>(thread)->GPR[2] = envp.addr();
|
||||
|
||||
return *this;
|
||||
}
|
||||
cpu_thread& run() override;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue