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 "frontend/A32/decoder/thumb16.h"
|
||||
#include "frontend/A32/decoder/thumb32.h"
|
||||
#include "frontend/A32/decoder/vfp.h"
|
||||
#include "frontend/A32/ir_emitter.h"
|
||||
#include "frontend/A32/location_descriptor.h"
|
||||
#include "frontend/A32/translate/conditional_state.h"
|
||||
|
@ -88,6 +89,12 @@ IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType m
|
|||
} else {
|
||||
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(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 {
|
||||
should_continue = visitor.thumb32_UDF();
|
||||
}
|
||||
|
@ -134,6 +141,12 @@ bool TranslateSingleThumbInstruction(IR::Block& block, LocationDescriptor descri
|
|||
thumb_instruction = Common::SwapHalves32(thumb_instruction);
|
||||
if (const auto decoder = DecodeThumb32<TranslatorVisitor>(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 {
|
||||
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
|
||||
};
|
||||
|
||||
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> invalid;
|
||||
|
||||
|
@ -176,6 +182,13 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
|
|||
"thumb32_STREXB",
|
||||
"thumb32_STREXD",
|
||||
"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) {
|
||||
|
@ -185,6 +198,17 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
|
|||
}
|
||||
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};
|
||||
}();
|
||||
|
||||
|
|
Loading…
Reference in a new issue