T32: Add VFP instructions
This commit is contained in:
parent
cd837c5b37
commit
d1e62b9993
2 changed files with 37 additions and 0 deletions
|
@ -11,6 +11,7 @@
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "frontend/A32/decoder/thumb16.h"
|
#include "frontend/A32/decoder/thumb16.h"
|
||||||
#include "frontend/A32/decoder/thumb32.h"
|
#include "frontend/A32/decoder/thumb32.h"
|
||||||
|
#include "frontend/A32/decoder/vfp.h"
|
||||||
#include "frontend/A32/ir_emitter.h"
|
#include "frontend/A32/ir_emitter.h"
|
||||||
#include "frontend/A32/location_descriptor.h"
|
#include "frontend/A32/location_descriptor.h"
|
||||||
#include "frontend/A32/translate/conditional_state.h"
|
#include "frontend/A32/translate/conditional_state.h"
|
||||||
|
@ -88,6 +89,12 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
|
||||||
} else {
|
} else {
|
||||||
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
|
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
|
||||||
should_continue = decoder->get().call(visitor, thumb_instruction);
|
should_continue = decoder->get().call(visitor, thumb_instruction);
|
||||||
|
} else if ((thumb_instruction & 0xEC000000) == 0xEC000000) {
|
||||||
|
if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(thumb_instruction)) {
|
||||||
|
should_continue = vfp_decoder->get().call(visitor, thumb_instruction);
|
||||||
|
} else {
|
||||||
|
should_continue = visitor.thumb32_UDF();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
should_continue = visitor.thumb32_UDF();
|
should_continue = visitor.thumb32_UDF();
|
||||||
}
|
}
|
||||||
|
@ -134,6 +141,12 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri
|
||||||
thumb_instruction = Common::SwapHalves32(thumb_instruction);
|
thumb_instruction = Common::SwapHalves32(thumb_instruction);
|
||||||
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
|
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(thumb_instruction)) {
|
||||||
should_continue = decoder->get().call(visitor, thumb_instruction);
|
should_continue = decoder->get().call(visitor, thumb_instruction);
|
||||||
|
} else if ((thumb_instruction & 0xEC000000) == 0xEC000000) {
|
||||||
|
if (const auto vfp_decoder = DecodeVFP<TranslatorVisitor>(thumb_instruction)) {
|
||||||
|
should_continue = vfp_decoder->get().call(visitor, thumb_instruction);
|
||||||
|
} else {
|
||||||
|
should_continue = visitor.thumb32_UDF();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
should_continue = visitor.thumb32_UDF();
|
should_continue = visitor.thumb32_UDF();
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,6 +158,12 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
|
||||||
#undef INST
|
#undef INST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const std::vector<std::tuple<std::string, const char*>> vfp_list {
|
||||||
|
#define INST(fn, name, bitstring) {#fn, bitstring},
|
||||||
|
#include "frontend/A32/decoder/vfp.inc"
|
||||||
|
#undef INST
|
||||||
|
};
|
||||||
|
|
||||||
std::vector<InstructionGenerator> generators;
|
std::vector<InstructionGenerator> generators;
|
||||||
std::vector<InstructionGenerator> invalid;
|
std::vector<InstructionGenerator> invalid;
|
||||||
|
|
||||||
|
@ -176,6 +182,13 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
|
||||||
"thumb32_STREXB",
|
"thumb32_STREXB",
|
||||||
"thumb32_STREXD",
|
"thumb32_STREXD",
|
||||||
"thumb32_STREXH",
|
"thumb32_STREXH",
|
||||||
|
|
||||||
|
// FPSCR is inaccurate
|
||||||
|
"vfp_VMRS",
|
||||||
|
|
||||||
|
// Unicorn has incorrect implementation (incorrect rounding and unsets CPSR.T??)
|
||||||
|
"vfp_VCVT_to_fixed",
|
||||||
|
"vfp_VCVT_from_fixed",
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& [fn, bitstring] : list) {
|
for (const auto& [fn, bitstring] : list) {
|
||||||
|
@ -185,6 +198,17 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
|
||||||
}
|
}
|
||||||
generators.emplace_back(InstructionGenerator{bitstring});
|
generators.emplace_back(InstructionGenerator{bitstring});
|
||||||
}
|
}
|
||||||
|
for (const auto& [fn, bs] : vfp_list) {
|
||||||
|
std::string bitstring = bs;
|
||||||
|
if (bitstring.substr(0, 4) == "cccc" || bitstring.substr(0, 4) == "----") {
|
||||||
|
bitstring.replace(0, 4, "1110");
|
||||||
|
}
|
||||||
|
if (std::find(do_not_test.begin(), do_not_test.end(), fn) != do_not_test.end()) {
|
||||||
|
invalid.emplace_back(InstructionGenerator{bitstring.c_str()});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
generators.emplace_back(InstructionGenerator{bitstring.c_str()});
|
||||||
|
}
|
||||||
return InstructionGeneratorInfo{generators, invalid};
|
return InstructionGeneratorInfo{generators, invalid};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue