early-access version 1584

This commit is contained in:
pineappleEA 2021-04-11 18:10:39 +02:00
parent cf7133d1e7
commit dd5dc4a807
14 changed files with 200 additions and 112 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access
=============
This is the source code for early-access 1583.
This is the source code for early-access 1584.
## Legal Notice

View file

@ -115,6 +115,9 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
// Start emitting.
code.align();
const u8* const entrypoint = code.getCurr();
code.SwitchToFarCode();
const u8* const entrypoint_far = code.getCurr();
code.SwitchToNearCode();
EmitCondPrelude(ctx);
@ -160,7 +163,7 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
const auto range = boost::icl::discrete_interval<u32>::closed(descriptor.PC(), end_location.PC() - 1);
block_ranges.AddRange(range, descriptor);
return RegisterBlock(descriptor, entrypoint, size);
return RegisterBlock(descriptor, entrypoint, entrypoint_far, size);
}
void A32EmitX64::ClearCache() {

View file

@ -90,6 +90,7 @@ struct Jit::Impl {
}
void ExceptionalExit() {
ClearExclusiveState();
if (!conf.wall_clock_cntpct) {
const s64 ticks = jit_state.cycles_to_run - jit_state.cycles_remaining;
conf.callbacks->AddTicks(ticks);

View file

@ -81,6 +81,9 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) {
// Start emitting.
code.align();
const u8* const entrypoint = code.getCurr();
code.SwitchToFarCode();
const u8* const entrypoint_far = code.getCurr();
code.SwitchToNearCode();
ASSERT(block.GetCondition() == IR::Cond::AL);
@ -126,7 +129,7 @@ A64EmitX64::BlockDescriptor A64EmitX64::Emit(IR::Block& block) {
const auto range = boost::icl::discrete_interval<u64>::closed(descriptor.PC(), end_location.PC() - 1);
block_ranges.AddRange(range, descriptor);
return RegisterBlock(descriptor, entrypoint, size);
return RegisterBlock(descriptor, entrypoint, entrypoint_far, size);
}
void A64EmitX64::ClearCache() {
@ -358,6 +361,7 @@ void A64EmitX64::GenTerminalHandlers() {
code.and_(code.ABI_PARAM1.cvt32(), fast_dispatch_table_mask);
code.lea(code.ABI_RETURN, code.ptr[code.ABI_PARAM1 + code.ABI_PARAM2]);
code.ret();
PerfMapRegister(fast_dispatch_table_lookup, code.getCurr(), "a64_fast_dispatch_table_lookup");
}
}

View file

@ -88,6 +88,7 @@ public:
}
void ExceptionalExit() {
ClearExclusiveState();
if (!conf.wall_clock_cntpct) {
const s64 ticks = jit_state.cycles_to_run - jit_state.cycles_remaining;
conf.callbacks->AddTicks(ticks);

View file

@ -120,7 +120,7 @@ size_t BlockOfCode::SpaceRemaining() const {
return 0;
if (current_far_ptr >= &top_[maxSize_])
return 0;
return std::min(current_near_ptr - reinterpret_cast<const u8*>(far_code_begin), current_far_ptr - &top_[maxSize_]);
return std::min(reinterpret_cast<const u8*>(far_code_begin) - current_near_ptr, &top_[maxSize_] - current_far_ptr);
}
void BlockOfCode::RunCode(void* jit_state, CodePtr code_ptr) const {

View file

@ -264,8 +264,11 @@ Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {
return pass;
}
EmitX64::BlockDescriptor EmitX64::RegisterBlock(const IR::LocationDescriptor& descriptor, CodePtr entrypoint, size_t size) {
EmitX64::BlockDescriptor EmitX64::RegisterBlock(const IR::LocationDescriptor& descriptor, CodePtr entrypoint, CodePtr entrypoint_far, size_t size) {
PerfMapRegister(entrypoint, code.getCurr(), LocationDescriptorToFriendlyName(descriptor));
code.SwitchToFarCode();
PerfMapRegister(entrypoint_far, code.getCurr(), LocationDescriptorToFriendlyName(descriptor) + "_far");
code.SwitchToNearCode();
Patch(descriptor, entrypoint);
BlockDescriptor block_desc{entrypoint, size};

View file

@ -94,7 +94,7 @@ protected:
virtual std::string LocationDescriptorToFriendlyName(const IR::LocationDescriptor&) const = 0;
void EmitAddCycles(size_t cycles);
Xbyak::Label EmitCond(IR::Cond cond);
BlockDescriptor RegisterBlock(const IR::LocationDescriptor& location_descriptor, CodePtr entrypoint, size_t size);
BlockDescriptor RegisterBlock(const IR::LocationDescriptor& location_descriptor, CodePtr entrypoint, CodePtr entrypoint_far, size_t size);
void PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, IR::LocationDescriptor target);
// Terminal instruction emitters

View file

@ -47,6 +47,11 @@ void OpenFile() {
namespace detail {
void PerfMapRegister(const void* start, const void* end, std::string_view friendly_name) {
if (start == end) {
// Nothing to register
return;
}
std::lock_guard guard{mutex};
if (!file) {

View file

@ -6,8 +6,8 @@ INST(arm_ISB, "ISB", "1111010101111111111100000110oooo
// Branch instructions
INST(arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv") // v5
INST(arm_BLX_reg, "BLX (reg)", "cccc000100101111111111110011mmmm") // v5
INST(arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv") // all
INST(arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv") // all
INST(arm_B, "B", "cccc1010vvvvvvvvvvvvvvvvvvvvvvvv") // v1
INST(arm_BL, "BL", "cccc1011vvvvvvvvvvvvvvvvvvvvvvvv") // v1
INST(arm_BX, "BX", "cccc000100101111111111110001mmmm") // v4T
INST(arm_BXJ, "BXJ", "cccc000100101111111111110010mmmm") // v5J
@ -25,59 +25,59 @@ INST(arm_MRRC, "MRRC", "cccc11000101uuuuttttppppooooMMMM
INST(arm_STC, "STC", "cccc110pudw0nnnnDDDDppppvvvvvvvv") // v2 (STC2: v5)
// Data Processing instructions
INST(arm_ADC_imm, "ADC (imm)", "cccc0010101Snnnnddddrrrrvvvvvvvv") // all
INST(arm_ADC_reg, "ADC (reg)", "cccc0000101Snnnnddddvvvvvrr0mmmm") // all
INST(arm_ADC_rsr, "ADC (rsr)", "cccc0000101Snnnnddddssss0rr1mmmm") // all
INST(arm_ADD_imm, "ADD (imm)", "cccc0010100Snnnnddddrrrrvvvvvvvv") // all
INST(arm_ADD_reg, "ADD (reg)", "cccc0000100Snnnnddddvvvvvrr0mmmm") // all
INST(arm_ADD_rsr, "ADD (rsr)", "cccc0000100Snnnnddddssss0rr1mmmm") // all
INST(arm_AND_imm, "AND (imm)", "cccc0010000Snnnnddddrrrrvvvvvvvv") // all
INST(arm_AND_reg, "AND (reg)", "cccc0000000Snnnnddddvvvvvrr0mmmm") // all
INST(arm_AND_rsr, "AND (rsr)", "cccc0000000Snnnnddddssss0rr1mmmm") // all
INST(arm_BIC_imm, "BIC (imm)", "cccc0011110Snnnnddddrrrrvvvvvvvv") // all
INST(arm_BIC_reg, "BIC (reg)", "cccc0001110Snnnnddddvvvvvrr0mmmm") // all
INST(arm_BIC_rsr, "BIC (rsr)", "cccc0001110Snnnnddddssss0rr1mmmm") // all
INST(arm_CMN_imm, "CMN (imm)", "cccc00110111nnnn0000rrrrvvvvvvvv") // all
INST(arm_CMN_reg, "CMN (reg)", "cccc00010111nnnn0000vvvvvrr0mmmm") // all
INST(arm_CMN_rsr, "CMN (rsr)", "cccc00010111nnnn0000ssss0rr1mmmm") // all
INST(arm_CMP_imm, "CMP (imm)", "cccc00110101nnnn0000rrrrvvvvvvvv") // all
INST(arm_CMP_reg, "CMP (reg)", "cccc00010101nnnn0000vvvvvrr0mmmm") // all
INST(arm_CMP_rsr, "CMP (rsr)", "cccc00010101nnnn0000ssss0rr1mmmm") // all
INST(arm_EOR_imm, "EOR (imm)", "cccc0010001Snnnnddddrrrrvvvvvvvv") // all
INST(arm_EOR_reg, "EOR (reg)", "cccc0000001Snnnnddddvvvvvrr0mmmm") // all
INST(arm_EOR_rsr, "EOR (rsr)", "cccc0000001Snnnnddddssss0rr1mmmm") // all
INST(arm_MOV_imm, "MOV (imm)", "cccc0011101S0000ddddrrrrvvvvvvvv") // all
INST(arm_MOV_reg, "MOV (reg)", "cccc0001101S0000ddddvvvvvrr0mmmm") // all
INST(arm_MOV_rsr, "MOV (rsr)", "cccc0001101S0000ddddssss0rr1mmmm") // all
INST(arm_MVN_imm, "MVN (imm)", "cccc0011111S0000ddddrrrrvvvvvvvv") // all
INST(arm_MVN_reg, "MVN (reg)", "cccc0001111S0000ddddvvvvvrr0mmmm") // all
INST(arm_MVN_rsr, "MVN (rsr)", "cccc0001111S0000ddddssss0rr1mmmm") // all
INST(arm_ORR_imm, "ORR (imm)", "cccc0011100Snnnnddddrrrrvvvvvvvv") // all
INST(arm_ORR_reg, "ORR (reg)", "cccc0001100Snnnnddddvvvvvrr0mmmm") // all
INST(arm_ORR_rsr, "ORR (rsr)", "cccc0001100Snnnnddddssss0rr1mmmm") // all
INST(arm_RSB_imm, "RSB (imm)", "cccc0010011Snnnnddddrrrrvvvvvvvv") // all
INST(arm_RSB_reg, "RSB (reg)", "cccc0000011Snnnnddddvvvvvrr0mmmm") // all
INST(arm_RSB_rsr, "RSB (rsr)", "cccc0000011Snnnnddddssss0rr1mmmm") // all
INST(arm_RSC_imm, "RSC (imm)", "cccc0010111Snnnnddddrrrrvvvvvvvv") // all
INST(arm_RSC_reg, "RSC (reg)", "cccc0000111Snnnnddddvvvvvrr0mmmm") // all
INST(arm_RSC_rsr, "RSC (rsr)", "cccc0000111Snnnnddddssss0rr1mmmm") // all
INST(arm_SBC_imm, "SBC (imm)", "cccc0010110Snnnnddddrrrrvvvvvvvv") // all
INST(arm_SBC_reg, "SBC (reg)", "cccc0000110Snnnnddddvvvvvrr0mmmm") // all
INST(arm_SBC_rsr, "SBC (rsr)", "cccc0000110Snnnnddddssss0rr1mmmm") // all
INST(arm_SUB_imm, "SUB (imm)", "cccc0010010Snnnnddddrrrrvvvvvvvv") // all
INST(arm_SUB_reg, "SUB (reg)", "cccc0000010Snnnnddddvvvvvrr0mmmm") // all
INST(arm_SUB_rsr, "SUB (rsr)", "cccc0000010Snnnnddddssss0rr1mmmm") // all
INST(arm_TEQ_imm, "TEQ (imm)", "cccc00110011nnnn0000rrrrvvvvvvvv") // all
INST(arm_TEQ_reg, "TEQ (reg)", "cccc00010011nnnn0000vvvvvrr0mmmm") // all
INST(arm_TEQ_rsr, "TEQ (rsr)", "cccc00010011nnnn0000ssss0rr1mmmm") // all
INST(arm_TST_imm, "TST (imm)", "cccc00110001nnnn0000rrrrvvvvvvvv") // all
INST(arm_TST_reg, "TST (reg)", "cccc00010001nnnn0000vvvvvrr0mmmm") // all
INST(arm_TST_rsr, "TST (rsr)", "cccc00010001nnnn0000ssss0rr1mmmm") // all
INST(arm_ADC_imm, "ADC (imm)", "cccc0010101Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_ADC_reg, "ADC (reg)", "cccc0000101Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_ADC_rsr, "ADC (rsr)", "cccc0000101Snnnnddddssss0rr1mmmm") // v1
INST(arm_ADD_imm, "ADD (imm)", "cccc0010100Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_ADD_reg, "ADD (reg)", "cccc0000100Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_ADD_rsr, "ADD (rsr)", "cccc0000100Snnnnddddssss0rr1mmmm") // v1
INST(arm_AND_imm, "AND (imm)", "cccc0010000Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_AND_reg, "AND (reg)", "cccc0000000Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_AND_rsr, "AND (rsr)", "cccc0000000Snnnnddddssss0rr1mmmm") // v1
INST(arm_BIC_imm, "BIC (imm)", "cccc0011110Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_BIC_reg, "BIC (reg)", "cccc0001110Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_BIC_rsr, "BIC (rsr)", "cccc0001110Snnnnddddssss0rr1mmmm") // v1
INST(arm_CMN_imm, "CMN (imm)", "cccc00110111nnnn0000rrrrvvvvvvvv") // v1
INST(arm_CMN_reg, "CMN (reg)", "cccc00010111nnnn0000vvvvvrr0mmmm") // v1
INST(arm_CMN_rsr, "CMN (rsr)", "cccc00010111nnnn0000ssss0rr1mmmm") // v1
INST(arm_CMP_imm, "CMP (imm)", "cccc00110101nnnn0000rrrrvvvvvvvv") // v1
INST(arm_CMP_reg, "CMP (reg)", "cccc00010101nnnn0000vvvvvrr0mmmm") // v1
INST(arm_CMP_rsr, "CMP (rsr)", "cccc00010101nnnn0000ssss0rr1mmmm") // v1
INST(arm_EOR_imm, "EOR (imm)", "cccc0010001Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_EOR_reg, "EOR (reg)", "cccc0000001Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_EOR_rsr, "EOR (rsr)", "cccc0000001Snnnnddddssss0rr1mmmm") // v1
INST(arm_MOV_imm, "MOV (imm)", "cccc0011101S0000ddddrrrrvvvvvvvv") // v1
INST(arm_MOV_reg, "MOV (reg)", "cccc0001101S0000ddddvvvvvrr0mmmm") // v1
INST(arm_MOV_rsr, "MOV (rsr)", "cccc0001101S0000ddddssss0rr1mmmm") // v1
INST(arm_MVN_imm, "MVN (imm)", "cccc0011111S0000ddddrrrrvvvvvvvv") // v1
INST(arm_MVN_reg, "MVN (reg)", "cccc0001111S0000ddddvvvvvrr0mmmm") // v1
INST(arm_MVN_rsr, "MVN (rsr)", "cccc0001111S0000ddddssss0rr1mmmm") // v1
INST(arm_ORR_imm, "ORR (imm)", "cccc0011100Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_ORR_reg, "ORR (reg)", "cccc0001100Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_ORR_rsr, "ORR (rsr)", "cccc0001100Snnnnddddssss0rr1mmmm") // v1
INST(arm_RSB_imm, "RSB (imm)", "cccc0010011Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_RSB_reg, "RSB (reg)", "cccc0000011Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_RSB_rsr, "RSB (rsr)", "cccc0000011Snnnnddddssss0rr1mmmm") // v1
INST(arm_RSC_imm, "RSC (imm)", "cccc0010111Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_RSC_reg, "RSC (reg)", "cccc0000111Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_RSC_rsr, "RSC (rsr)", "cccc0000111Snnnnddddssss0rr1mmmm") // v1
INST(arm_SBC_imm, "SBC (imm)", "cccc0010110Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_SBC_reg, "SBC (reg)", "cccc0000110Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_SBC_rsr, "SBC (rsr)", "cccc0000110Snnnnddddssss0rr1mmmm") // v1
INST(arm_SUB_imm, "SUB (imm)", "cccc0010010Snnnnddddrrrrvvvvvvvv") // v1
INST(arm_SUB_reg, "SUB (reg)", "cccc0000010Snnnnddddvvvvvrr0mmmm") // v1
INST(arm_SUB_rsr, "SUB (rsr)", "cccc0000010Snnnnddddssss0rr1mmmm") // v1
INST(arm_TEQ_imm, "TEQ (imm)", "cccc00110011nnnn0000rrrrvvvvvvvv") // v1
INST(arm_TEQ_reg, "TEQ (reg)", "cccc00010011nnnn0000vvvvvrr0mmmm") // v1
INST(arm_TEQ_rsr, "TEQ (rsr)", "cccc00010011nnnn0000ssss0rr1mmmm") // v1
INST(arm_TST_imm, "TST (imm)", "cccc00110001nnnn0000rrrrvvvvvvvv") // v1
INST(arm_TST_reg, "TST (reg)", "cccc00010001nnnn0000vvvvvrr0mmmm") // v1
INST(arm_TST_rsr, "TST (rsr)", "cccc00010001nnnn0000ssss0rr1mmmm") // v1
// Exception Generating instructions
INST(arm_BKPT, "BKPT", "cccc00010010vvvvvvvvvvvv0111vvvv") // v5
INST(arm_SVC, "SVC", "cccc1111vvvvvvvvvvvvvvvvvvvvvvvv") // all
INST(arm_UDF, "UDF", "111001111111------------1111----") // all
INST(arm_SVC, "SVC", "cccc1111vvvvvvvvvvvvvvvvvvvvvvvv") // v1
INST(arm_UDF, "UDF", "111001111111------------1111----")
// Extension instructions
INST(arm_SXTB, "SXTB", "cccc011010101111ddddrr000111mmmm") // v6
@ -132,62 +132,62 @@ INST(arm_LDAEXH, "LDAEXH", "cccc00011111nnnndddd111010011111
INST(arm_LDREXH, "LDREXH", "cccc00011111nnnndddd111110011111") // v6K
// Load/Store instructions
INST(arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------")
INST(arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----")
INST(arm_LDRHT, "LDRHT (A1)", "----0000-111------------1011----")
INST(arm_LDRHT, "LDRHT (A1)", "----0000-1111111--------1011----")
INST(arm_LDRHT, "LDRHT (A2)", "----0000-011--------00001011----")
INST(arm_LDRSBT, "LDRSBT (A1)", "----0000-111------------1101----")
INST(arm_LDRSBT, "LDRSBT (A2)", "----0000-011--------00001101----")
INST(arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----")
INST(arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----")
INST(arm_LDRT, "LDRT (A1)", "----0100-011--------------------")
INST(arm_LDRT, "LDRT (A2)", "----0110-011---------------0----")
INST(arm_STRBT, "STRBT (A1)", "----0100-110--------------------")
INST(arm_STRBT, "STRBT (A2)", "----0110-110---------------0----")
INST(arm_STRHT, "STRHT (A1)", "----0000-110------------1011----")
INST(arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----")
INST(arm_STRT, "STRT (A1)", "----0100-010--------------------")
INST(arm_STRT, "STRT (A2)", "----0110-010---------------0----")
INST(arm_LDR_lit, "LDR (lit)", "cccc0101u0011111ttttvvvvvvvvvvvv")
INST(arm_LDR_imm, "LDR (imm)", "cccc010pu0w1nnnnttttvvvvvvvvvvvv")
INST(arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnttttvvvvvrr0mmmm")
INST(arm_LDRB_lit, "LDRB (lit)", "cccc0101u1011111ttttvvvvvvvvvvvv")
INST(arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnttttvvvvvvvvvvvv")
INST(arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnttttvvvvvrr0mmmm")
INST(arm_LDRD_lit, "LDRD (lit)", "cccc0001u1001111ttttvvvv1101vvvv")
INST(arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------") // v1
INST(arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----") // v1
INST(arm_LDRHT, "LDRHT (A1)", "----0000-111------------1011----") // v6T2
INST(arm_LDRHT, "LDRHT (A1)", "----0000-1111111--------1011----") // v6T2
INST(arm_LDRHT, "LDRHT (A2)", "----0000-011--------00001011----") // v6T2
INST(arm_LDRSBT, "LDRSBT (A1)", "----0000-111------------1101----") // v6T2
INST(arm_LDRSBT, "LDRSBT (A2)", "----0000-011--------00001101----") // v6T2
INST(arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----") // v6T2
INST(arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----") // v6T2
INST(arm_LDRT, "LDRT (A1)", "----0100-011--------------------") // v1
INST(arm_LDRT, "LDRT (A2)", "----0110-011---------------0----") // v1
INST(arm_STRBT, "STRBT (A1)", "----0100-110--------------------") // v1
INST(arm_STRBT, "STRBT (A2)", "----0110-110---------------0----") // v1
INST(arm_STRHT, "STRHT (A1)", "----0000-110------------1011----") // v6T2
INST(arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----") // v6T2
INST(arm_STRT, "STRT (A1)", "----0100-010--------------------") // v1
INST(arm_STRT, "STRT (A2)", "----0110-010---------------0----") // v1
INST(arm_LDR_lit, "LDR (lit)", "cccc0101u0011111ttttvvvvvvvvvvvv") // v1
INST(arm_LDR_imm, "LDR (imm)", "cccc010pu0w1nnnnttttvvvvvvvvvvvv") // v1
INST(arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnttttvvvvvrr0mmmm") // v1
INST(arm_LDRB_lit, "LDRB (lit)", "cccc0101u1011111ttttvvvvvvvvvvvv") // v1
INST(arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnttttvvvvvvvvvvvv") // v1
INST(arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnttttvvvvvrr0mmmm") // v1
INST(arm_LDRD_lit, "LDRD (lit)", "cccc0001u1001111ttttvvvv1101vvvv") // v5E
INST(arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnttttvvvv1101vvvv") // v5E
INST(arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnntttt00001101mmmm") // v5E
INST(arm_LDRH_lit, "LDRH (lit)", "cccc000pu1w11111ttttvvvv1011vvvv")
INST(arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnttttvvvv1011vvvv")
INST(arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnntttt00001011mmmm")
INST(arm_LDRSB_lit, "LDRSB (lit)", "cccc0001u1011111ttttvvvv1101vvvv")
INST(arm_LDRSB_imm, "LDRSB (imm)", "cccc000pu1w1nnnnttttvvvv1101vvvv")
INST(arm_LDRSB_reg, "LDRSB (reg)", "cccc000pu0w1nnnntttt00001101mmmm")
INST(arm_LDRSH_lit, "LDRSH (lit)", "cccc0001u1011111ttttvvvv1111vvvv")
INST(arm_LDRSH_imm, "LDRSH (imm)", "cccc000pu1w1nnnnttttvvvv1111vvvv")
INST(arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnntttt00001111mmmm")
INST(arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnttttvvvvvvvvvvvv")
INST(arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnttttvvvvvrr0mmmm")
INST(arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnttttvvvvvvvvvvvv")
INST(arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnttttvvvvvrr0mmmm")
INST(arm_LDRH_lit, "LDRH (lit)", "cccc000pu1w11111ttttvvvv1011vvvv") // v4
INST(arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnttttvvvv1011vvvv") // v4
INST(arm_LDRH_reg, "LDRH (reg)", "cccc000pu0w1nnnntttt00001011mmmm") // v4
INST(arm_LDRSB_lit, "LDRSB (lit)", "cccc0001u1011111ttttvvvv1101vvvv") // v4
INST(arm_LDRSB_imm, "LDRSB (imm)", "cccc000pu1w1nnnnttttvvvv1101vvvv") // v4
INST(arm_LDRSB_reg, "LDRSB (reg)", "cccc000pu0w1nnnntttt00001101mmmm") // v4
INST(arm_LDRSH_lit, "LDRSH (lit)", "cccc0001u1011111ttttvvvv1111vvvv") // v4
INST(arm_LDRSH_imm, "LDRSH (imm)", "cccc000pu1w1nnnnttttvvvv1111vvvv") // v4
INST(arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnntttt00001111mmmm") // v4
INST(arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnttttvvvvvvvvvvvv") // v1
INST(arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnttttvvvvvrr0mmmm") // v1
INST(arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnttttvvvvvvvvvvvv") // v1
INST(arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnttttvvvvvrr0mmmm") // v1
INST(arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnttttvvvv1111vvvv") // v5E
INST(arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnntttt00001111mmmm") // v5E
INST(arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnttttvvvv1011vvvv")
INST(arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnntttt00001011mmmm")
INST(arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnttttvvvv1011vvvv") // v4
INST(arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnntttt00001011mmmm") // v4
// Load/Store Multiple instructions
INST(arm_LDM, "LDM", "cccc100010w1nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_LDMDA, "LDMDA", "cccc100000w1nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_LDMDB, "LDMDB", "cccc100100w1nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_LDMIB, "LDMIB", "cccc100110w1nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------") // all
INST(arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------") // all
INST(arm_STM, "STM", "cccc100010w0nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_STMDA, "STMDA", "cccc100000w0nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_STMDB, "STMDB", "cccc100100w0nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_STMIB, "STMIB", "cccc100110w0nnnnxxxxxxxxxxxxxxxx") // all
INST(arm_STM_usr, "STM (usr reg)", "----100--100--------------------") // all
INST(arm_LDM, "LDM", "cccc100010w1nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_LDMDA, "LDMDA", "cccc100000w1nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_LDMDB, "LDMDB", "cccc100100w1nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_LDMIB, "LDMIB", "cccc100110w1nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_LDM_usr, "LDM (usr reg)", "----100--101--------------------") // v1
INST(arm_LDM_eret, "LDM (exce ret)", "----100--1-1----1---------------") // v1
INST(arm_STM, "STM", "cccc100010w0nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_STMDA, "STMDA", "cccc100000w0nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_STMDB, "STMDB", "cccc100100w0nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_STMIB, "STMIB", "cccc100110w0nnnnxxxxxxxxxxxxxxxx") // v1
INST(arm_STM_usr, "STM (usr reg)", "----100--100--------------------") // v1
// Miscellaneous instructions
INST(arm_BFC, "BFC", "cccc0111110vvvvvddddvvvvv0011111") // v6T2

View file

@ -11,7 +11,7 @@ INST(thumb32_LDMDB, "LDMDB/LDMEA", "1110100100W1nnnniiiiii
//INST(thumb32_RFE_2, "RFE", "1110100110-1--------------------")
// Load/Store Dual, Load/Store Exclusive, Table Branch
//INST(thumb32_STREX, "STREX", "111010000100--------------------")
INST(thumb32_STREX, "STREX", "111010000100nnnnttttddddiiiiiiii")
//INST(thumb32_LDREX, "LDREX", "111010000101--------------------")
INST(thumb32_STRD_imm_1, "STRD (imm)", "11101000U110nnnnttttssssiiiiiiii")
INST(thumb32_STRD_imm_2, "STRD (imm)", "11101001U1W0nnnnttttssssiiiiiiii")
@ -19,9 +19,9 @@ INST(thumb32_LDRD_lit_1, "LDRD (lit)", "11101000U1111111ttttss
INST(thumb32_LDRD_lit_2, "LDRD (lit)", "11101001U1W11111ttttssssiiiiiiii")
INST(thumb32_LDRD_imm_1, "LDRD (imm)", "11101000U111nnnnttttssssiiiiiiii")
INST(thumb32_LDRD_imm_2, "LDRD (imm)", "11101001U1W1nnnnttttssssiiiiiiii")
//INST(thumb32_STREXB, "STREXB", "111010001100------------0100----")
//INST(thumb32_STREXH, "STREXH", "111010001100------------0101----")
//INST(thumb32_STREXD, "STREXD", "111010001100------------0111----")
INST(thumb32_STREXB, "STREXB", "111010001100nnnntttt11110100dddd")
INST(thumb32_STREXH, "STREXH", "111010001100nnnntttt11110101dddd")
INST(thumb32_STREXD, "STREXD", "111010001100nnnnttttuuuu0111dddd")
INST(thumb32_TBB, "TBB", "111010001101nnnn111100000000mmmm")
INST(thumb32_TBH, "TBH", "111010001101nnnn111100000001mmmm")
//INST(thumb32_LDREXB, "LDREXB", "111010001101------------0100----")

View file

@ -135,6 +135,67 @@ bool ThumbTranslatorVisitor::thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Re
return StoreDual(*this, true, U, W, n, t, t2, imm8);
}
bool ThumbTranslatorVisitor::thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
if (d == n || d == t) {
return UnpredictableInstruction();
}
const auto address = ir.Add(ir.GetRegister(n), ir.Imm32(imm8.ZeroExtend()));
const auto value = ir.GetRegister(t);
const auto passed = ir.ExclusiveWriteMemory32(address, value);
ir.SetRegister(d, passed);
return true;
}
bool ThumbTranslatorVisitor::thumb32_STREXB(Reg n, Reg t, Reg d) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
if (d == n || d == t) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantByte(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory8(address, value);
ir.SetRegister(d, passed);
return true;
}
bool ThumbTranslatorVisitor::thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d) {
if (d == Reg::PC || t == Reg::PC || t2 == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
if (d == n || d == t || d == t2) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
const auto value_lo = ir.GetRegister(t);
const auto value_hi = ir.GetRegister(t2);
const auto passed = ir.ExclusiveWriteMemory64(address, value_lo, value_hi);
ir.SetRegister(d, passed);
return true;
}
bool ThumbTranslatorVisitor::thumb32_STREXH(Reg n, Reg t, Reg d) {
if (d == Reg::PC || t == Reg::PC || n == Reg::PC) {
return UnpredictableInstruction();
}
if (d == n || d == t) {
return UnpredictableInstruction();
}
const auto address = ir.GetRegister(n);
const auto value = ir.LeastSignificantHalf(ir.GetRegister(t));
const auto passed = ir.ExclusiveWriteMemory16(address, value);
ir.SetRegister(d, passed);
return true;
}
bool ThumbTranslatorVisitor::thumb32_TBB(Reg n, Reg m) {
return TableBranch(*this, n, m, false);
}

View file

@ -186,6 +186,10 @@ struct ThumbTranslatorVisitor final {
bool thumb32_LDRD_lit_2(bool U, bool W, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_1(bool U, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STRD_imm_2(bool U, bool W, Reg n, Reg t, Reg t2, Imm<8> imm8);
bool thumb32_STREX(Reg n, Reg t, Reg d, Imm<8> imm8);
bool thumb32_STREXB(Reg n, Reg t, Reg d);
bool thumb32_STREXD(Reg n, Reg t, Reg t2, Reg d);
bool thumb32_STREXH(Reg n, Reg t, Reg d);
bool thumb32_TBB(Reg n, Reg m);
bool thumb32_TBH(Reg n, Reg m);

View file

@ -166,6 +166,12 @@ std::vector<u16> GenRandomThumbInst(u32 pc, bool is_last_inst, A32::ITState it_s
"thumb16_BKPT",
"thumb16_IT",
"thumb16_SETEND",
// Exclusive load/stores
"thumb32_STREX",
"thumb32_STREXB",
"thumb32_STREXD",
"thumb32_STREXH",
};
for (const auto& [fn, bitstring] : list) {