From 8e2ff56569e5319dbcdb223b4263023497af2b87 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 23 Jul 2018 15:57:48 +0100 Subject: [PATCH] u128: Add StickyLogicalShiftRight --- src/common/u128.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/common/u128.h | 4 ++++ 2 files changed, 43 insertions(+) diff --git a/src/common/u128.cpp b/src/common/u128.cpp index 73a825a1..8bad425f 100644 --- a/src/common/u128.cpp +++ b/src/common/u128.cpp @@ -92,4 +92,43 @@ u128 operator>>(u128 operand, int amount) { return {}; } +u128 StickyLogicalShiftRight(u128 operand, int amount) { + if (amount < 0) { + return operand << -amount; + } + + if (amount == 0) { + return operand; + } + + if (amount < 64) { + u128 result; + result.lower = (operand.lower >> amount) | (operand.upper << (64 - amount)); + result.upper = (operand.upper >> amount); + // Sticky bit + if ((operand.lower << (64 - amount)) != 0) { + result.lower |= 1; + } + return result; + } + + if (amount < 128) { + u128 result; + result.lower = operand.upper >> (amount - 64); + // Sticky bit + if (operand.lower != 0) { + result.lower |= 1; + } + if ((operand.upper << (128 - amount)) != 0) { + result.lower |= 1; + } + return result; + } + + if (operand.lower != 0 || operand.upper != 0) { + return u128(1); + } + return {}; +} + } // namespace Dynarmic diff --git a/src/common/u128.h b/src/common/u128.h index 19d44bb6..da184d10 100644 --- a/src/common/u128.h +++ b/src/common/u128.h @@ -91,4 +91,8 @@ inline bool operator!=(u128 a, u128 b) { u128 operator<<(u128 operand, int amount); u128 operator>>(u128 operand, int amount); +/// LSB is a "sticky-bit". +/// If a 1 is shifted off, the LSB would be set. +u128 StickyLogicalShiftRight(u128 operand, int amount); + } // namespace Dynarmic