------------------------------------------------------------------------ Writes a jump at the current x86Ptr, which targets a pre-established target address. (usually a backwards jump) slideForward - used internally by xSmartJump to indicate that the jump target is going to slide forward in the event of an 8 bit displacement.
| 180 | // to slide forward in the event of an 8 bit displacement. |
| 181 | // |
| 182 | __emitinline void xJccKnownTarget(JccComparisonType comparison, const void* target, bool slideForward) |
| 183 | { |
| 184 | // Calculate the potential j8 displacement first, assuming an instruction length of 2: |
| 185 | sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2); |
| 186 | |
| 187 | const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0; |
| 188 | displacement8 -= slideVal; |
| 189 | |
| 190 | if (slideForward) |
| 191 | { |
| 192 | pxAssertMsg(displacement8 >= 0, "Used slideForward on a backward jump; nothing to slide!"); |
| 193 | } |
| 194 | |
| 195 | if (is_s8(displacement8)) |
| 196 | xJcc8(comparison, displacement8); |
| 197 | else |
| 198 | { |
| 199 | // Perform a 32 bit jump instead. :( |
| 200 | s32* bah = xJcc32(comparison); |
| 201 | sptr distance = (sptr)target - (sptr)xGetPtr(); |
| 202 | |
| 203 | // This assert won't physically happen on x86 targets |
| 204 | pxAssertMsg(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target is too far away, needs an indirect register"); |
| 205 | |
| 206 | *bah = (s32)distance; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | // Low-level jump instruction! Specify a comparison type and a target in void* form, and |
| 211 | // a jump (either 8 or 32 bit) is generated. |