mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 04:02:42 +01:00
ARMv7: CMP_REG, LDR_IMM, LDR_LIT, STR_REG, SUB_REG
sceLibc: exit and printf drafts This actually allows to display hello world.
This commit is contained in:
parent
31c71b4a48
commit
df72f5e37c
@ -24,6 +24,7 @@ namespace Log
|
||||
HLE,
|
||||
PPU,
|
||||
SPU,
|
||||
ARMv7,
|
||||
TTY,
|
||||
};
|
||||
|
||||
@ -35,7 +36,7 @@ namespace Log
|
||||
};
|
||||
|
||||
//well I'd love make_array() but alas manually counting is not the end of the world
|
||||
static const std::array<LogTypeName, 8> gTypeNameTable = { {
|
||||
static const std::array<LogTypeName, 9> gTypeNameTable = { {
|
||||
{ GENERAL, "G: " },
|
||||
{ LOADER, "LDR: " },
|
||||
{ MEMORY, "MEM: " },
|
||||
@ -43,6 +44,7 @@ namespace Log
|
||||
{ HLE, "HLE: " },
|
||||
{ PPU, "PPU: " },
|
||||
{ SPU, "SPU: " },
|
||||
{ ARMv7, "ARM: " },
|
||||
{ TTY, "TTY: " }
|
||||
} };
|
||||
|
||||
@ -121,6 +123,7 @@ static struct { inline operator Log::LogType() { return Log::LogType::RSX; } } R
|
||||
static struct { inline operator Log::LogType() { return Log::LogType::HLE; } } HLE;
|
||||
static struct { inline operator Log::LogType() { return Log::LogType::PPU; } } PPU;
|
||||
static struct { inline operator Log::LogType() { return Log::LogType::SPU; } } SPU;
|
||||
static struct { inline operator Log::LogType() { return Log::LogType::ARMv7; } } ARMv7;
|
||||
static struct { inline operator Log::LogType() { return Log::LogType::TTY; } } TTY;
|
||||
|
||||
inline void log_message(Log::LogType type, Log::LogSeverity sev, const char* text)
|
||||
|
@ -210,7 +210,7 @@ void ARMv7Interpreter::ASR_REG(const u32 data, const ARMv7_encoding type)
|
||||
void ARMv7Interpreter::B(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 jump = 0; // jump = instr_size + imm32
|
||||
u32 jump = 0; // jump = instr_size + imm32 ???
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@ -222,12 +222,12 @@ void ARMv7Interpreter::B(const u32 data, const ARMv7_encoding type)
|
||||
throw "SVC";
|
||||
}
|
||||
|
||||
jump = 2 + sign<9, u32>((data & 0xff) << 1);
|
||||
jump = 4 + sign<9, u32>((data & 0xff) << 1);
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
jump = 2 + sign<12, u32>((data & 0x7ff) << 1);
|
||||
jump = 4 + sign<12, u32>((data & 0x7ff) << 1);
|
||||
break;
|
||||
}
|
||||
case T3:
|
||||
@ -235,7 +235,7 @@ void ARMv7Interpreter::B(const u32 data, const ARMv7_encoding type)
|
||||
cond = (data >> 6) & 0xf;
|
||||
if (cond >= 0xe)
|
||||
{
|
||||
throw "Related encodings";
|
||||
throw "B_T3: Related encodings";
|
||||
}
|
||||
|
||||
u32 s = (data >> 26) & 0x1;
|
||||
@ -254,7 +254,7 @@ void ARMv7Interpreter::B(const u32 data, const ARMv7_encoding type)
|
||||
}
|
||||
case A1:
|
||||
{
|
||||
cond = (data >> 28) & 0xf;
|
||||
cond = data >> 28;
|
||||
jump = 1 + 4 + sign<26, u32>((data & 0xffffff) << 2);
|
||||
break;
|
||||
}
|
||||
@ -457,7 +457,7 @@ void ARMv7Interpreter::CB_Z(const u32 data, const ARMv7_encoding type)
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if ((CPU.read_gpr(data & 0x7) == 0) ^ (data & 0x800))
|
||||
if ((CPU.read_gpr(data & 0x7) == 0) ^ ((data & 0x800) != 0))
|
||||
{
|
||||
CPU.SetBranch(CPU.PC + 2 + ((data & 0xf8) >> 2) + ((data & 0x200) >> 3));
|
||||
}
|
||||
@ -513,11 +513,47 @@ void ARMv7Interpreter::CMP_IMM(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
void ARMv7Interpreter::CMP_REG(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 n = 0;
|
||||
u32 m = 0;
|
||||
auto shift_t = SRType_LSL;
|
||||
u32 shift_n = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
n = (data & 0x7);
|
||||
m = (data & 0x38) >> 3;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
n = (data & 0x80) >> 4 | (data & 0x7);
|
||||
m = (data & 0x78) >> 3;
|
||||
break;
|
||||
}
|
||||
case T3:
|
||||
{
|
||||
n = (data & 0xf0000) >> 16;
|
||||
m = (data & 0xf);
|
||||
shift_t = DecodeImmShift((data & 0x30) >> 4, (data & 0x7000) >> 10 | (data & 0xc0) >> 6, &shift_n);
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
bool carry, overflow;
|
||||
const u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, true);
|
||||
const u32 res = AddWithCarry(CPU.read_gpr(n), ~shifted, true, carry, overflow);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
CPU.APSR.C = carry;
|
||||
CPU.APSR.V = overflow;
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7Interpreter::CMP_RSR(const u32 data, const ARMv7_encoding type)
|
||||
@ -566,7 +602,7 @@ void ARMv7Interpreter::IT(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
if ((data & 0xf) == 0)
|
||||
{
|
||||
throw "Related encodings";
|
||||
throw "IT_T1: Related encodings";
|
||||
}
|
||||
|
||||
CPU.ITSTATE.IT = data & 0xff;
|
||||
@ -616,11 +652,83 @@ void ARMv7Interpreter::LDMIB(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
void ARMv7Interpreter::LDR_IMM(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 t = 0;
|
||||
u32 n = 13;
|
||||
u32 imm32 = 0;
|
||||
bool index = true;
|
||||
bool add = true;
|
||||
bool wback = false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case A1: throw __FUNCTION__;
|
||||
case T1:
|
||||
{
|
||||
t = (data & 0x7);
|
||||
n = (data & 0x38) >> 3;
|
||||
imm32 = (data & 0x7c0) >> 4;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
t = (data & 0x700) >> 8;
|
||||
imm32 = (data & 0xff) << 2;
|
||||
break;
|
||||
}
|
||||
case T3:
|
||||
{
|
||||
t = (data & 0xf000) >> 12;
|
||||
n = (data & 0xf0000) >> 16;
|
||||
imm32 = (data & 0xfff);
|
||||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDR (literal)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T4:
|
||||
{
|
||||
t = (data & 0xf000) >> 12;
|
||||
n = (data & 0xf0000) >> 16;
|
||||
imm32 = (data & 0xff);
|
||||
index = (data & 0x400);
|
||||
add = (data & 0x200);
|
||||
wback = (data & 0x100);
|
||||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "LDR (literal)";
|
||||
}
|
||||
if (index && add && !wback)
|
||||
{
|
||||
throw "LDRT";
|
||||
}
|
||||
if (n == 13 && !index && add && wback && imm32 == 4)
|
||||
{
|
||||
throw "POP";
|
||||
}
|
||||
if (!index && !wback)
|
||||
{
|
||||
throw "LDR_IMM_T4: undefined";
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
const u32 offset_addr = add ? CPU.read_gpr(n) + imm32 : CPU.read_gpr(n) - imm32;
|
||||
const u32 addr = index ? offset_addr : CPU.read_gpr(n);
|
||||
|
||||
if (wback)
|
||||
{
|
||||
CPU.write_gpr(n, offset_addr);
|
||||
}
|
||||
|
||||
CPU.write_gpr(t, vm::psv::read32(addr));
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7Interpreter::LDR_LIT(const u32 data, const ARMv7_encoding type)
|
||||
@ -855,13 +963,13 @@ void ARMv7Interpreter::MOV_IMM(const u32 data, const ARMv7_encoding type)
|
||||
imm32 = sign<8, u32>(data & 0xff);
|
||||
break;
|
||||
}
|
||||
//case T2:
|
||||
//{
|
||||
// set_flags = data & 0x100000;
|
||||
// d = (data >> 8) & 0xf;
|
||||
// imm32 = ThumbExpandImm_C((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff), carry);
|
||||
// break;
|
||||
//}
|
||||
case T2:
|
||||
{
|
||||
set_flags = data & 0x100000;
|
||||
d = (data >> 8) & 0xf;
|
||||
imm32 = ThumbExpandImm_C((data & 0x4000000) >> 15 | (data & 0x7000) >> 4 | (data & 0xff), carry, carry);
|
||||
break;
|
||||
}
|
||||
case T3:
|
||||
{
|
||||
set_flags = false;
|
||||
@ -1115,7 +1223,7 @@ void ARMv7Interpreter::POP(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
reg_list = ((data & 0x100) << 6) | (data & 0xff);
|
||||
reg_list = ((data & 0x100) << 7) | (data & 0xff);
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
@ -1830,7 +1938,7 @@ void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
if (n == 0xf)
|
||||
{
|
||||
throw "STR_IMM_T3 UNDEFINED";
|
||||
throw "STR_IMM_T3: undefined";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1853,7 +1961,7 @@ void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type)
|
||||
}
|
||||
if (n == 15 || (!index && !wback))
|
||||
{
|
||||
throw "STR_IMM_T4 UNDEFINED";
|
||||
throw "STR_IMM_T4: undefined";
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1877,11 +1985,55 @@ void ARMv7Interpreter::STR_IMM(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
void ARMv7Interpreter::STR_REG(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 t = 0;
|
||||
u32 n = 0;
|
||||
u32 m = 0;
|
||||
bool index = true;
|
||||
bool add = true;
|
||||
bool wback = false;
|
||||
auto shift_t = SRType_LSL;
|
||||
u32 shift_n = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
t = (data & 0x7);
|
||||
n = (data & 0x38) >> 3;
|
||||
m = (data & 0x1c0) >> 6;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
t = (data & 0xf000) >> 12;
|
||||
n = (data & 0xf0000) >> 16;
|
||||
m = (data & 0xf);
|
||||
shift_n = (data & 0x30) >> 4;
|
||||
|
||||
if (n == 15)
|
||||
{
|
||||
throw "STR_REG_T2: undefined";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
const u32 offset = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C);
|
||||
const u32 offset_addr = add ? CPU.read_gpr(n) + offset : CPU.read_gpr(n) - offset;
|
||||
const u32 addr = index ? offset_addr : CPU.read_gpr(n);
|
||||
|
||||
vm::psv::write32(addr, CPU.read_gpr(t));
|
||||
|
||||
if (wback)
|
||||
{
|
||||
CPU.write_gpr(n, offset_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1953,11 +2105,63 @@ void ARMv7Interpreter::SUB_IMM(const u32 data, const ARMv7_encoding type)
|
||||
|
||||
void ARMv7Interpreter::SUB_REG(const u32 data, const ARMv7_encoding type)
|
||||
{
|
||||
bool set_flags = !CPU.ITSTATE;
|
||||
u32 cond = CPU.ITSTATE.advance();
|
||||
u32 d = 0;
|
||||
u32 n = 0;
|
||||
u32 m = 0;
|
||||
auto shift_t = SRType_LSL;
|
||||
u32 shift_n = 0;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T1:
|
||||
{
|
||||
d = (data & 0x7);
|
||||
n = (data & 0x38) >> 3;
|
||||
m = (data & 0x1c0) >> 6;
|
||||
break;
|
||||
}
|
||||
case T2:
|
||||
{
|
||||
d = (data & 0xf00) >> 8;
|
||||
n = (data & 0xf0000) >> 16;
|
||||
m = (data & 0xf);
|
||||
set_flags = (data & 0x100000);
|
||||
shift_t = DecodeImmShift((data & 0x30) >> 4, (data & 0x7000) >> 10 | (data & 0xc0) >> 6, &shift_n);
|
||||
|
||||
if (d == 15 && set_flags)
|
||||
{
|
||||
throw "CMP (register)";
|
||||
}
|
||||
if (n == 13)
|
||||
{
|
||||
throw "SUB (SP minus register)";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case A1: throw __FUNCTION__;
|
||||
default: throw __FUNCTION__;
|
||||
}
|
||||
|
||||
if (ConditionPassed(cond))
|
||||
{
|
||||
u32 shifted = Shift(CPU.read_gpr(m), shift_t, shift_n, CPU.APSR.C);
|
||||
if (set_flags)
|
||||
{
|
||||
bool carry, overflow;
|
||||
u32 res = AddWithCarry(CPU.read_gpr(n), ~shifted, true, carry, overflow);
|
||||
CPU.write_gpr(d, res);
|
||||
CPU.APSR.N = res >> 31;
|
||||
CPU.APSR.Z = res == 0;
|
||||
CPU.APSR.C = carry;
|
||||
CPU.APSR.V = overflow;
|
||||
}
|
||||
else
|
||||
{
|
||||
CPU.write_gpr(d, CPU.read_gpr(n) - shifted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ARMv7Interpreter::SUB_RSR(const u32 data, const ARMv7_encoding type)
|
||||
|
@ -10,7 +10,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
enum SRType
|
||||
enum SRType : u32
|
||||
{
|
||||
SRType_None,
|
||||
SRType_LSL,
|
||||
@ -93,7 +93,7 @@ public:
|
||||
return len - 1 - HighestSetBit(x, len);
|
||||
}
|
||||
|
||||
SRType DecodeImmShift(u8 type, u8 imm5, uint* shift_n)
|
||||
SRType DecodeImmShift(u32 type, u32 imm5, u32* shift_n)
|
||||
{
|
||||
SRType shift_t = SRType_None;
|
||||
|
||||
@ -217,7 +217,7 @@ public:
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T Shift(T value, SRType type, uint amount, bool carry_in)
|
||||
template<typename T> T Shift(T value, SRType type, u32 amount, bool carry_in)
|
||||
{
|
||||
bool carry_out;
|
||||
return Shift_C(value, type, amount, carry_in, carry_out);
|
||||
@ -239,6 +239,29 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
u32 ThumbExpandImm_C(u32 imm12, bool carry_in, bool& carry_out)
|
||||
{
|
||||
if ((imm12 & 0xc00) >> 10)
|
||||
{
|
||||
u32 unrotated_value = (imm12 & 0x7f) | 0x80;
|
||||
|
||||
return ROR_C(unrotated_value, (imm12 & 0xf80) >> 7, carry_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
carry_out = carry_in;
|
||||
|
||||
u32 imm8 = imm12 & 0xff;
|
||||
switch ((imm12 & 0x300) >> 8)
|
||||
{
|
||||
case 0: return imm8;
|
||||
case 1: return imm8 << 16 | imm8;
|
||||
case 2: return imm8 << 24 | imm8 << 8;
|
||||
default: return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ConditionPassed(u32 cond) const
|
||||
{
|
||||
bool result = false;
|
||||
|
@ -103,7 +103,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBranch(value);
|
||||
SetBranch(value & ~1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/ARMv7/PSVFuncList.h"
|
||||
|
||||
extern psv_log_base& sceLibc;
|
||||
@ -12,17 +14,25 @@ namespace sce_libc_func
|
||||
|
||||
void exit()
|
||||
{
|
||||
sceLibc.Todo(__FUNCTION__);
|
||||
sceLibc.Error("exit()");
|
||||
Emu.Pause();
|
||||
sceLibc.Success("Process finished");
|
||||
CallAfter([]()
|
||||
{
|
||||
Emu.Stop();
|
||||
});
|
||||
}
|
||||
|
||||
void printf()
|
||||
void printf(vm::psv::ptr<const char> fmt)
|
||||
{
|
||||
sceLibc.Todo(__FUNCTION__);
|
||||
sceLibc.Error("printf(fmt_addr=0x%x)", fmt.addr());
|
||||
|
||||
LOG_NOTICE(TTY, "%s", fmt.get_ptr());
|
||||
}
|
||||
|
||||
void __cxa_set_dso_handle_main()
|
||||
{
|
||||
sceLibc.Todo(__FUNCTION__);
|
||||
sceLibc.Error("__cxa_set_dso_handle_main()");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Emu/ARMv7/PSVFuncList.h"
|
||||
#include "ELF32.h"
|
||||
|
||||
#define LOADER_DEBUG
|
||||
//#define LOADER_DEBUG
|
||||
|
||||
void Elf32_Ehdr::Show()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user