2016-07-04 14:37:50 +01:00
|
|
|
/* This file is part of the dynarmic project.
|
|
|
|
* Copyright (c) 2016 MerryMage
|
|
|
|
* This software may be used and distributed according to the terms of the GNU
|
|
|
|
* General Public License version 2 or any later version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "common/assert.h"
|
|
|
|
#include "frontend/arm_types.h"
|
2016-07-14 13:28:20 +01:00
|
|
|
#include "frontend/decoder/arm.h"
|
2016-07-04 14:37:50 +01:00
|
|
|
#include "frontend/ir/ir.h"
|
2016-07-12 09:04:47 +01:00
|
|
|
#include "frontend/ir_emitter.h"
|
2016-07-04 14:37:50 +01:00
|
|
|
#include "frontend/translate.h"
|
|
|
|
|
|
|
|
namespace Dynarmic {
|
|
|
|
namespace Arm {
|
|
|
|
|
2016-07-14 13:28:20 +01:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
struct ArmTranslatorVisitor final {
|
|
|
|
explicit ArmTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) {
|
|
|
|
ASSERT_MSG(!descriptor.TFlag, "The processor must be in Arm mode");
|
|
|
|
}
|
|
|
|
|
|
|
|
IREmitter ir;
|
|
|
|
|
|
|
|
bool TranslateThisInstruction() {
|
|
|
|
ir.SetTerm(IR::Term::Interpret(ir.current_location));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnpredictableInstruction() {
|
|
|
|
ASSERT_MSG(false, "UNPREDICTABLE");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool arm_UDF() {
|
|
|
|
return TranslateThisInstruction();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // local namespace
|
|
|
|
|
2016-07-04 14:37:50 +01:00
|
|
|
IR::Block TranslateArm(LocationDescriptor descriptor, MemoryRead32FuncType memory_read_32) {
|
2016-07-14 13:28:20 +01:00
|
|
|
ArmTranslatorVisitor visitor{descriptor};
|
|
|
|
|
|
|
|
bool should_continue = true;
|
|
|
|
while (should_continue) {
|
|
|
|
const u32 arm_pc = visitor.ir.current_location.arm_pc;
|
|
|
|
const u32 arm_instruction = (*memory_read_32)(arm_pc);
|
|
|
|
|
|
|
|
const auto decoder = DecodeArm<ArmTranslatorVisitor>(arm_instruction);
|
|
|
|
if (decoder) {
|
|
|
|
should_continue = decoder->call(visitor, arm_instruction);
|
|
|
|
} else {
|
|
|
|
should_continue = visitor.arm_UDF();
|
|
|
|
}
|
|
|
|
|
|
|
|
visitor.ir.current_location.arm_pc += 4;
|
|
|
|
visitor.ir.block.cycle_count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return visitor.ir.block;
|
2016-07-04 14:37:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Arm
|
|
|
|
} // namespace Dynarmic
|