Просмотр исходного кода

emitter: Support arbitrary FixupBranch targets.

bunnei 10 лет назад
Родитель
Сommit
e5d417213c
2 измененных файлов с 17 добавлено и 0 удалено
  1. 16 0
      src/common/x64/emitter.cpp
  2. 1 0
      src/common/x64/emitter.h

+ 16 - 0
src/common/x64/emitter.cpp

@@ -531,6 +531,22 @@ void XEmitter::SetJumpTarget(const FixupBranch& branch)
     }
 }
 
+void XEmitter::SetJumpTarget(const FixupBranch& branch, const u8* target)
+{
+    if (branch.type == 0)
+    {
+        s64 distance = (s64)(target - branch.ptr);
+        ASSERT_MSG(distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true");
+        branch.ptr[-1] = (u8)(s8)distance;
+    }
+    else if (branch.type == 1)
+    {
+        s64 distance = (s64)(target - branch.ptr);
+        ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register");
+        ((s32*)branch.ptr)[-1] = (s32)distance;
+    }
+}
+
 //Single byte opcodes
 //There is no PUSHAD/POPAD in 64-bit mode.
 void XEmitter::INT3() {Write8(0xCC);}

+ 1 - 0
src/common/x64/emitter.h

@@ -431,6 +431,7 @@ public:
     void J_CC(CCFlags conditionCode, const u8* addr, bool force5Bytes = false);
 
     void SetJumpTarget(const FixupBranch& branch);
+    void SetJumpTarget(const FixupBranch& branch, const u8* target);
 
     void SETcc(CCFlags flag, OpArg dest);
     // Note: CMOV brings small if any benefit on current cpus.