2018-01-04 23:05:27 +00:00
|
|
|
/* This file is part of the dynarmic project.
|
|
|
|
* Copyright (c) 2018 MerryMage
|
|
|
|
* This software may be used and distributed according to the terms of the GNU
|
|
|
|
* General Public License version 2 or any later version.
|
|
|
|
*/
|
|
|
|
|
2018-01-07 00:11:57 +00:00
|
|
|
#include "frontend/A64/decoder/a64.h"
|
2018-01-04 23:05:27 +00:00
|
|
|
#include "frontend/A64/location_descriptor.h"
|
|
|
|
#include "frontend/A64/translate/impl/impl.h"
|
|
|
|
#include "frontend/A64/translate/translate.h"
|
|
|
|
#include "frontend/ir/basic_block.h"
|
|
|
|
|
|
|
|
namespace Dynarmic {
|
|
|
|
namespace A64 {
|
|
|
|
|
2018-01-07 00:11:57 +00:00
|
|
|
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
|
2018-01-12 19:34:25 +00:00
|
|
|
IR::Block block{descriptor};
|
|
|
|
TranslatorVisitor visitor{block, descriptor};
|
2018-01-07 00:11:57 +00:00
|
|
|
|
|
|
|
bool should_continue = true;
|
|
|
|
while (should_continue) {
|
|
|
|
const u64 pc = visitor.ir.current_location.PC();
|
|
|
|
const u32 instruction = memory_read_code(pc);
|
|
|
|
|
|
|
|
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {
|
|
|
|
should_continue = decoder->call(visitor, instruction);
|
|
|
|
} else {
|
|
|
|
should_continue = visitor.InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4);
|
2018-01-12 19:34:25 +00:00
|
|
|
block.CycleCount()++;
|
2018-01-07 00:11:57 +00:00
|
|
|
}
|
|
|
|
|
2018-01-12 19:34:25 +00:00
|
|
|
ASSERT_MSG(block.HasTerminal(), "Terminal has not been set");
|
2018-01-07 00:11:57 +00:00
|
|
|
|
2018-01-12 19:34:25 +00:00
|
|
|
block.SetEndLocation(visitor.ir.current_location);
|
2018-01-07 00:11:57 +00:00
|
|
|
|
2018-01-12 19:34:25 +00:00
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction) {
|
|
|
|
TranslatorVisitor visitor{block, descriptor};
|
|
|
|
|
|
|
|
bool should_continue = true;
|
|
|
|
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {
|
|
|
|
should_continue = decoder->call(visitor, instruction);
|
|
|
|
} else {
|
|
|
|
should_continue = visitor.InterpretThisInstruction();
|
|
|
|
}
|
|
|
|
|
|
|
|
visitor.ir.current_location = visitor.ir.current_location.AdvancePC(4);
|
|
|
|
block.CycleCount()++;
|
|
|
|
|
|
|
|
block.SetEndLocation(visitor.ir.current_location);
|
|
|
|
|
|
|
|
return should_continue;
|
2018-01-04 23:05:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace A64
|
|
|
|
} // namespace Dynarmic
|