Fix Thumb BLX (imm), BL (imm) for negative immediates
This commit is contained in:
parent
3f11a149d7
commit
95588d3faa
2 changed files with 18 additions and 2 deletions
|
@ -789,7 +789,7 @@ struct ThumbTranslatorVisitor final {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thumb32_BL_imm(Imm11 hi, Imm11 lo) {
|
bool thumb32_BL_imm(Imm11 hi, Imm11 lo) {
|
||||||
s32 imm32 = Common::SignExtend<32, s32>((hi << 12) | (lo << 1));
|
s32 imm32 = Common::SignExtend<23, s32>((hi << 12) | (lo << 1));
|
||||||
// BL <label>
|
// BL <label>
|
||||||
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.arm_pc + 4) | 1));
|
ir.SetRegister(Reg::LR, ir.Imm32((ir.current_location.arm_pc + 4) | 1));
|
||||||
auto new_location = ir.current_location;
|
auto new_location = ir.current_location;
|
||||||
|
@ -799,7 +799,7 @@ struct ThumbTranslatorVisitor final {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool thumb32_BLX_imm(Imm11 hi, Imm11 lo) {
|
bool thumb32_BLX_imm(Imm11 hi, Imm11 lo) {
|
||||||
s32 imm32 = Common::SignExtend<32, s32>((hi << 12) | (lo << 1));
|
s32 imm32 = Common::SignExtend<23, s32>((hi << 12) | (lo << 1));
|
||||||
if ((lo & 1) != 0) {
|
if ((lo & 1) != 0) {
|
||||||
return UnpredictableInstruction();
|
return UnpredictableInstruction();
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,3 +152,19 @@ TEST_CASE( "thumb: bl +#234584", "[thumb]" ) {
|
||||||
REQUIRE( jit.Regs()[15] == 0x39458 );
|
REQUIRE( jit.Regs()[15] == 0x39458 );
|
||||||
REQUIRE( jit.Cpsr() == 0x00000030 ); // Thumb, User-mode
|
REQUIRE( jit.Cpsr() == 0x00000030 ); // Thumb, User-mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE( "thumb: bl -#42", "[thumb]" ) {
|
||||||
|
Dynarmic::Jit jit{GetUserCallbacks()};
|
||||||
|
code_mem.fill({});
|
||||||
|
code_mem[0] = 0xF7FF; code_mem[1] = 0xFFE9; // bl -#42
|
||||||
|
code_mem[2] = 0xE7FE; // b +#0
|
||||||
|
|
||||||
|
jit.Regs()[15] = 0; // PC = 0
|
||||||
|
jit.Cpsr() = 0x00000030; // Thumb, User-mode
|
||||||
|
|
||||||
|
jit.Run(1);
|
||||||
|
|
||||||
|
REQUIRE( jit.Regs()[14] == (0x4 | 1) );
|
||||||
|
REQUIRE( jit.Regs()[15] == 0xFFFFFFD6 );
|
||||||
|
REQUIRE( jit.Cpsr() == 0x00000030 ); // Thumb, User-mode
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue