simplify sh4 execute loop

This commit is contained in:
Anthony Pesch 2015-09-28 16:59:21 -07:00
parent 51eb95e184
commit 4308e570e5
10 changed files with 26 additions and 31 deletions

View File

@ -14,7 +14,7 @@ bool AICA::Init() {
return true;
}
uint32_t AICA::Execute(uint32_t cycles) {
int AICA::Execute(int cycles) {
// uint16_t MCIEB = *reinterpret_cast<uint16_t *>(&aica_regs_[MCIEB_OFFSET]);
// uint16_t MCIPD = *reinterpret_cast<uint16_t *>(&aica_regs_[MCIPD_OFFSET]);

View File

@ -14,10 +14,10 @@ class AICA : public hw::Device {
public:
AICA(hw::Dreamcast *dc);
uint32_t GetClockFrequency() { return 22579200; }
int GetClockFrequency() { return 22579200; }
bool Init();
uint32_t Execute(uint32_t cycles);
int Execute(int cycles);
static uint32_t ReadRegister(void *ctx, uint32_t addr);
static void WriteRegister(void *ctx, uint32_t addr, uint32_t value);

View File

@ -10,8 +10,8 @@ class Device {
public:
virtual ~Device(){};
virtual uint32_t GetClockFrequency() = 0;
virtual uint32_t Execute(uint32_t cycles) = 0;
virtual int GetClockFrequency() = 0;
virtual int Execute(int cycles) = 0;
};
}
}

View File

@ -76,14 +76,14 @@ void Scheduler::Tick(const std::chrono::nanoseconds &delta) {
for (auto &info : devices_) {
auto delta = std::chrono::duration_cast<std::chrono::nanoseconds>(
target_time - info.current_time);
uint32_t cycles_per_second = info.device->GetClockFrequency();
uint32_t cycles_to_run = static_cast<uint32_t>(
(delta.count() * static_cast<uint64_t>(cycles_per_second)) /
int cycles_per_second = info.device->GetClockFrequency();
int cycles_to_run = static_cast<int>(
(delta.count() * static_cast<int64_t>(cycles_per_second)) /
NS_PER_SEC);
uint32_t ran = info.device->Execute(cycles_to_run);
int ran = info.device->Execute(cycles_to_run);
info.current_time += std::chrono::nanoseconds(
(ran * static_cast<uint64_t>(NS_PER_SEC)) / cycles_per_second);
(ran * static_cast<int64_t>(NS_PER_SEC)) / cycles_per_second);
}
base_time_ = target_time;

View File

@ -53,10 +53,10 @@ bool SH4::Init() {
void SH4::SetPC(uint32_t pc) { ctx_.pc = pc; }
uint32_t SH4::Execute(uint32_t cycles) {
int SH4::Execute(int cycles) {
PROFILER_RUNTIME("SH4::Execute");
uint32_t remaining = cycles;
int remaining = cycles;
// update timers
for (int i = 0; i < 3; i++) {
@ -64,18 +64,11 @@ uint32_t SH4::Execute(uint32_t cycles) {
RunTimer(i, cycles >> 2);
}
while (ctx_.pc) {
while (ctx_.pc && remaining > 0) {
RuntimeBlock *block = runtime_.GetBlock(ctx_.pc, &ctx_);
// be careful not to wrap around
uint32_t next_remaining = remaining - block->guest_cycles();
if (next_remaining > remaining) {
break;
}
// run the block
ctx_.pc = block->call()(&memory_, &ctx_, block);
remaining = next_remaining;
remaining -= block->guest_cycles();
CheckPendingCacheReset();
CheckPendingInterrupts();
@ -459,7 +452,7 @@ bool SH4::TimerEnabled(int n) { //
return TSTR & (1 << n);
}
void SH4::RunTimer(int n, uint32_t cycles) {
void SH4::RunTimer(int n, int cycles) {
static const int tcr_shift[] = {2, 4, 6, 8, 10, 0, 0, 0};
if (!TimerEnabled(n)) {

View File

@ -118,11 +118,11 @@ class SH4 : public hw::Device {
public:
SH4(hw::Memory &memory, jit::Runtime &runtime);
uint32_t GetClockFrequency() { return 200000000; }
int GetClockFrequency() { return 200000000; }
bool Init();
void SetPC(uint32_t pc);
uint32_t Execute(uint32_t cycles);
int Execute(int cycles);
// DMAC
void DDT(int channel, DDTRW rw, uint32_t addr);
@ -165,7 +165,7 @@ class SH4 : public hw::Device {
// TMU
bool TimerEnabled(int n);
void RunTimer(int n, uint32_t cycles);
void RunTimer(int n, int cycles);
hw::Memory &memory_;
jit::Runtime &runtime_;

View File

@ -14,7 +14,8 @@ InterpreterBlock::InterpreterBlock(int guest_cycles, IntInstr *instrs,
void InterpreterBlock::Dump() { LOG_INFO("Unimplemented"); }
uint32_t InterpreterBlock::Call(Memory *memory, void *guest_ctx, RuntimeBlock *block) {
uint32_t InterpreterBlock::Call(Memory *memory, void *guest_ctx,
RuntimeBlock *block) {
InterpreterBlock *self = reinterpret_cast<InterpreterBlock *>(block);
IntValue *registers = reinterpret_cast<IntValue *>(
alloca(int_num_registers * sizeof(IntValue)));

View File

@ -18,7 +18,8 @@ class InterpreterBlock : public RuntimeBlock {
void Dump();
private:
static uint32_t Call(hw::Memory *memory, void *guest_ctx, RuntimeBlock *block);
static uint32_t Call(hw::Memory *memory, void *guest_ctx,
RuntimeBlock *block);
IntInstr *instrs_;
int num_instrs_;

View File

@ -23,8 +23,7 @@ enum {
MAX_BLOCKS = 0x1000000 >> BLOCK_ADDR_SHIFT,
};
#define BLOCK_OFFSET(addr) \
((addr & BLOCK_ADDR_MASK) >> BLOCK_ADDR_SHIFT)
#define BLOCK_OFFSET(addr) ((addr & BLOCK_ADDR_MASK) >> BLOCK_ADDR_SHIFT)
Runtime::Runtime(Memory &memory, frontend::Frontend &frontend,
backend::Backend &backend)

View File

@ -16,11 +16,12 @@ class Frontend;
}
class RuntimeBlock;
typedef uint32_t(*RuntimeCall)(hw::Memory *, void *, RuntimeBlock *);
typedef uint32_t (*RuntimeCall)(hw::Memory *, void *, RuntimeBlock *);
class RuntimeBlock {
public:
RuntimeBlock(int guest_cycles, RuntimeCall call) : guest_cycles_(guest_cycles), call_(call) {}
RuntimeBlock(int guest_cycles, RuntimeCall call)
: guest_cycles_(guest_cycles), call_(call) {}
virtual ~RuntimeBlock() {}
int guest_cycles() { return guest_cycles_; }