early-access version 1730
This commit is contained in:
93
externals/dynarmic/tests/print_info.cpp
vendored
93
externals/dynarmic/tests/print_info.cpp
vendored
@@ -12,35 +12,35 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <dynarmic/A32/a32.h>
|
||||
#include <dynarmic/A32/disassembler.h>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/llvm_disassemble.h"
|
||||
#include "frontend/A32/decoder/arm.h"
|
||||
#include "frontend/A32/decoder/asimd.h"
|
||||
#include "frontend/A32/decoder/vfp.h"
|
||||
#include "frontend/A32/location_descriptor.h"
|
||||
#include "frontend/A32/translate/impl/translate_arm.h"
|
||||
#include "frontend/A32/translate/translate.h"
|
||||
#include "frontend/A64/decoder/a64.h"
|
||||
#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"
|
||||
#include "ir_opt/passes.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#include "dynarmic/common/bit_util.h"
|
||||
#include "dynarmic/common/common_types.h"
|
||||
#include "dynarmic/common/llvm_disassemble.h"
|
||||
#include "dynarmic/frontend/A32/decoder/arm.h"
|
||||
#include "dynarmic/frontend/A32/decoder/asimd.h"
|
||||
#include "dynarmic/frontend/A32/decoder/vfp.h"
|
||||
#include "dynarmic/frontend/A32/location_descriptor.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/translate.h"
|
||||
#include "dynarmic/frontend/A32/translate/translate.h"
|
||||
#include "dynarmic/frontend/A64/decoder/a64.h"
|
||||
#include "dynarmic/frontend/A64/location_descriptor.h"
|
||||
#include "dynarmic/frontend/A64/translate/impl/impl.h"
|
||||
#include "dynarmic/frontend/A64/translate/translate.h"
|
||||
#include "dynarmic/interface/A32/a32.h"
|
||||
#include "dynarmic/interface/A32/disassembler.h"
|
||||
#include "dynarmic/ir/basic_block.h"
|
||||
#include "dynarmic/ir/opt/passes.h"
|
||||
|
||||
using namespace Dynarmic;
|
||||
|
||||
const char* GetNameOfA32Instruction(u32 instruction) {
|
||||
if (auto vfp_decoder = A32::DecodeVFP<A32::ArmTranslatorVisitor>(instruction)) {
|
||||
if (auto vfp_decoder = A32::DecodeVFP<A32::TranslatorVisitor>(instruction)) {
|
||||
return vfp_decoder->get().GetName();
|
||||
} else if (auto asimd_decoder = A32::DecodeASIMD<A32::ArmTranslatorVisitor>(instruction)) {
|
||||
} else if (auto asimd_decoder = A32::DecodeASIMD<A32::TranslatorVisitor>(instruction)) {
|
||||
return asimd_decoder->get().GetName();
|
||||
} else if (auto decoder = A32::DecodeArm<A32::ArmTranslatorVisitor>(instruction)) {
|
||||
} else if (auto decoder = A32::DecodeArm<A32::TranslatorVisitor>(instruction)) {
|
||||
return decoder->get().GetName();
|
||||
}
|
||||
return "<null>";
|
||||
@@ -95,6 +95,30 @@ void PrintA64Instruction(u32 instruction) {
|
||||
fmt::print("{}\n", IR::DumpBlock(block));
|
||||
}
|
||||
|
||||
void PrintThumbInstruction(u32 instruction) {
|
||||
const size_t inst_size = (instruction >> 16) == 0 ? 2 : 4;
|
||||
if (inst_size == 4)
|
||||
instruction = Common::SwapHalves32(instruction);
|
||||
|
||||
fmt::print("{:08x} {}\n", instruction, Common::DisassembleAArch32(true, 0, (u8*)&instruction, inst_size));
|
||||
|
||||
const A32::LocationDescriptor location{0, A32::PSR{0x1F0}, {}};
|
||||
IR::Block block{location};
|
||||
const bool should_continue = A32::TranslateSingleInstruction(block, location, instruction);
|
||||
fmt::print("should_continue: {}\n\n", should_continue);
|
||||
fmt::print("IR:\n");
|
||||
fmt::print("{}\n", IR::DumpBlock(block));
|
||||
|
||||
Optimization::A32GetSetElimination(block);
|
||||
Optimization::DeadCodeElimination(block);
|
||||
Optimization::ConstantPropagation(block);
|
||||
Optimization::DeadCodeElimination(block);
|
||||
Optimization::IdentityRemovalPass(block);
|
||||
|
||||
fmt::print("Optimized IR:\n");
|
||||
fmt::print("{}\n", IR::DumpBlock(block));
|
||||
}
|
||||
|
||||
class ExecEnv final : public Dynarmic::A32::UserCallbacks {
|
||||
public:
|
||||
u64 ticks_left = 0;
|
||||
@@ -164,7 +188,7 @@ void ExecuteA32Instruction(u32 instruction) {
|
||||
u32 cpsr = 0;
|
||||
u32 fpscr = 0;
|
||||
|
||||
const std::map<std::string, u32*> name_map = [®s, &ext_regs, &cpsr, &fpscr]{
|
||||
const std::map<std::string, u32*> name_map = [®s, &ext_regs, &cpsr, &fpscr] {
|
||||
std::map<std::string, u32*> name_map;
|
||||
for (size_t i = 0; i < regs.size(); i++) {
|
||||
name_map[fmt::format("r{}", i)] = ®s[i];
|
||||
@@ -180,7 +204,7 @@ void ExecuteA32Instruction(u32 instruction) {
|
||||
return name_map;
|
||||
}();
|
||||
|
||||
const auto get_line = [](){
|
||||
const auto get_line = []() {
|
||||
std::string line;
|
||||
std::getline(std::cin, line);
|
||||
std::transform(line.begin(), line.end(), line.begin(), [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
@@ -189,12 +213,15 @@ void ExecuteA32Instruction(u32 instruction) {
|
||||
|
||||
const auto get_value = [&get_line]() -> std::optional<u32> {
|
||||
std::string line = get_line();
|
||||
if (line.length() > 2 && line[0] == '0' && line[1] == 'x') line = line.substr(2);
|
||||
if (line.length() > 8) return std::nullopt;
|
||||
if (line.length() > 2 && line[0] == '0' && line[1] == 'x')
|
||||
line = line.substr(2);
|
||||
if (line.length() > 8)
|
||||
return std::nullopt;
|
||||
|
||||
char* endptr;
|
||||
const u32 value = strtol(line.c_str(), &endptr, 16);
|
||||
if (line.c_str() + line.length() != endptr) return std::nullopt;
|
||||
if (line.c_str() + line.length() != endptr)
|
||||
return std::nullopt;
|
||||
|
||||
return value;
|
||||
};
|
||||
@@ -230,7 +257,7 @@ void ExecuteA32Instruction(u32 instruction) {
|
||||
|
||||
const u32 initial_pc = regs[15];
|
||||
env.MemoryWrite32(initial_pc + 0, instruction);
|
||||
env.MemoryWrite32(initial_pc + 4, 0xEAFFFFFE); // B +0
|
||||
env.MemoryWrite32(initial_pc + 4, 0xEAFFFFFE); // B +0
|
||||
|
||||
cpu.Run();
|
||||
|
||||
@@ -259,11 +286,11 @@ void ExecuteA32Instruction(u32 instruction) {
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 3 || argc > 4) {
|
||||
fmt::print("usage: {} <a32/a64> <instruction_in_hex> [-exec]\n", argv[0]);
|
||||
fmt::print("usage: {} <a32/a64/thumb> <instruction_in_hex> [-exec]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* const hex_instruction = [argv]{
|
||||
const char* const hex_instruction = [argv] {
|
||||
if (strlen(argv[2]) > 2 && argv[2][0] == '0' && argv[2][1] == 'x') {
|
||||
return argv[2] + 2;
|
||||
}
|
||||
@@ -281,8 +308,10 @@ int main(int argc, char** argv) {
|
||||
PrintA32Instruction(instruction);
|
||||
} else if (strcmp(argv[1], "a64") == 0) {
|
||||
PrintA64Instruction(instruction);
|
||||
} else if (strcmp(argv[1], "t32") == 0 || strcmp(argv[1], "t16") == 0 || strcmp(argv[1], "thumb") == 0) {
|
||||
PrintThumbInstruction(instruction);
|
||||
} else {
|
||||
fmt::print("Invalid mode: {}\nValid values: a32, a64\n", argv[1]);
|
||||
fmt::print("Invalid mode: {}\nValid values: a32, a64, thumb\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -294,8 +323,8 @@ int main(int argc, char** argv) {
|
||||
|
||||
if (strcmp(argv[1], "a32") == 0) {
|
||||
ExecuteA32Instruction(instruction);
|
||||
} else if (strcmp(argv[1], "a64") == 0) {
|
||||
fmt::print("Executing a64 code not currently supported\n");
|
||||
} else {
|
||||
fmt::print("Executing in this mode not currently supported\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user