A64/translate: Allow for unpredictable behaviour to be defined

This commit is contained in:
MerryMage 2018-08-16 09:59:06 +01:00
parent d1d6f4feb5
commit cd40e4dae0
5 changed files with 22 additions and 6 deletions

View file

@ -158,6 +158,11 @@ struct UserConfig {
/// This is only used if page_table is not nullptr.
bool silently_mirror_page_table = true;
/// This option relates to translation. Generally when we run into an unpredictable
/// instruction the ExceptionRaised callback is called. If this is true, we define
/// definite behaviour for some unpredictable instructions.
bool define_unpredictable_behaviour = false;
// The below options relate to accuracy of floating-point emulation.
/// Determines how accurate NaN handling is.

View file

@ -199,7 +199,8 @@ private:
}
// JIT Compile
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); });
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour});
Optimization::A64CallbackConfigPass(ir_block, conf);
Optimization::A64GetSetElimination(ir_block);
Optimization::DeadCodeElimination(ir_block);

View file

@ -11,6 +11,7 @@
#include "frontend/A64/imm.h"
#include "frontend/A64/ir_emitter.h"
#include "frontend/A64/location_descriptor.h"
#include "frontend/A64/translate/translate.h"
#include "frontend/A64/types.h"
namespace Dynarmic::A64 {
@ -26,9 +27,10 @@ enum class MemOp {
struct TranslatorVisitor final {
using instruction_return_type = bool;
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor) : ir(block, descriptor) {}
explicit TranslatorVisitor(IR::Block& block, LocationDescriptor descriptor, TranslationOptions options) : ir(block, descriptor), options(std::move(options)) {}
A64::IREmitter ir;
TranslationOptions options;
bool InterpretThisInstruction();
bool UnpredictableInstruction();

View file

@ -12,9 +12,9 @@
namespace Dynarmic::A64 {
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) {
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options) {
IR::Block block{descriptor};
TranslatorVisitor visitor{block, descriptor};
TranslatorVisitor visitor{block, descriptor, std::move(options)};
bool should_continue = true;
while (should_continue) {
@ -39,7 +39,7 @@ IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory
}
bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor, u32 instruction) {
TranslatorVisitor visitor{block, descriptor};
TranslatorVisitor visitor{block, descriptor, {}};
bool should_continue = true;
if (auto decoder = Decode<TranslatorVisitor>(instruction)) {

View file

@ -21,13 +21,21 @@ class LocationDescriptor;
using MemoryReadCodeFuncType = std::function<u32(u64 vaddr)>;
struct TranslationOptions {
/// This changes what IR we emit when we translate an unpredictable instruction.
/// If this is false, the ExceptionRaised IR instruction is emitted.
/// If this is true, we define some behaviour for some instructions.
bool define_unpredictable_behaviour = false;
};
/**
* This function translates instructions in memory into our intermediate representation.
* @param descriptor The starting location of the basic block. Includes information like PC, FPCR state, &c.
* @param memory_read_code The function we should use to read emulated memory.
* @param options Configure how instructions are translated.
* @return A translated basic block in the intermediate representation.
*/
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code);
IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code, TranslationOptions options);
/**
* This function translates a single provided instruction into our intermediate representation.