diff options
Diffstat (limited to 'src/common/x64')
| -rw-r--r-- | src/common/x64/emitter.cpp | 28 | ||||
| -rw-r--r-- | src/common/x64/emitter.h | 2 | 
2 files changed, 30 insertions, 0 deletions
| diff --git a/src/common/x64/emitter.cpp b/src/common/x64/emitter.cpp index 1dcf2416c..5662f7f86 100644 --- a/src/common/x64/emitter.cpp +++ b/src/common/x64/emitter.cpp @@ -455,6 +455,18 @@ void XEmitter::CALL(const void* fnptr)      Write32(u32(distance));  } +FixupBranch XEmitter::CALL() +{ +    FixupBranch branch; +    branch.type = 1; +    branch.ptr = code + 5; + +    Write8(0xE8); +    Write32(0); + +    return branch; +} +  FixupBranch XEmitter::J(bool force5bytes)  {      FixupBranch branch; @@ -531,6 +543,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);} diff --git a/src/common/x64/emitter.h b/src/common/x64/emitter.h index 7c6548fb5..a33724146 100644 --- a/src/common/x64/emitter.h +++ b/src/common/x64/emitter.h @@ -425,12 +425,14 @@ public:  #undef CALL  #endif      void CALL(const void* fnptr); +    FixupBranch CALL();      void CALLptr(OpArg arg);      FixupBranch J_CC(CCFlags conditionCode, bool force5bytes = false);      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. | 
