|
|
@@ -23,16 +23,39 @@ type
|
|
|
static; inline;
|
|
|
|
|
|
/// <summary>
|
|
|
- /// Calculates Arithmetic shift right.
|
|
|
+ /// Calculates Left Shift. This was implemented to circumvent an *issue*
|
|
|
+ /// in FPC ARM when performing Shift Left with <b>AShiftBits > 32 .</b><br />
|
|
|
/// </summary>
|
|
|
- /// <param name="AValue">Int64 value to compute 'Asr' on.</param>
|
|
|
- /// <param name="AShiftBits">Byte, number of bits to shift value to.</param>
|
|
|
- /// <returns>Shifted value.</returns>
|
|
|
- /// <remarks>
|
|
|
- /// Emulated Implementation was gotten from FreePascal sources
|
|
|
- /// </remarks>
|
|
|
+ /// <param name="AValue">
|
|
|
+ /// Int32 value to compute 'LS' on.
|
|
|
+ /// </param>
|
|
|
+ /// <param name="AShiftBits">
|
|
|
+ /// Int32, number of bits to shift value to.
|
|
|
+ /// </param>
|
|
|
+ /// <returns>
|
|
|
+ /// Shifted value.
|
|
|
+ /// </returns>
|
|
|
|
|
|
- class function Asr64(AValue: Int64; AShiftBits: Byte): Int64;
|
|
|
+ class function LeftShift32(AValue: Int32; AShiftBits: Int32): Int32;
|
|
|
+ static; inline;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates Negative Left Shift. This was implemented to circumvent an
|
|
|
+ /// *issue* in FPC ARM when performing Shift Left on certain values with a
|
|
|
+ /// Negative Shift Bits. In some C Compilers, such operations are
|
|
|
+ /// "Undefined"
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="AValue">
|
|
|
+ /// Int32 value to compute 'NLS' on.
|
|
|
+ /// </param>
|
|
|
+ /// <param name="AShiftBits">
|
|
|
+ /// Int32, number of bits to shift value to. This Number Must be Negative
|
|
|
+ /// </param>
|
|
|
+ /// <returns>
|
|
|
+ /// Shifted value.
|
|
|
+ /// </returns>
|
|
|
+
|
|
|
+ class function NegativeLeftShift32(AValue: Int32; AShiftBits: Int32): Int32;
|
|
|
static; inline;
|
|
|
|
|
|
end;
|
|
|
@@ -44,26 +67,27 @@ implementation
|
|
|
class function TBits.Asr32(AValue: Int32; AShiftBits: Byte): Int32;
|
|
|
|
|
|
begin
|
|
|
-{$IFDEF FPC}
|
|
|
+{$IF DEFINED(FPC) AND (NOT DEFINED(CPUARM))}
|
|
|
Result := SarLongInt(AValue, AShiftBits);
|
|
|
{$ELSE}
|
|
|
Result := Int32(UInt32(UInt32(UInt32(AValue) shr (AShiftBits and 31)) or
|
|
|
(UInt32(Int32(UInt32(0 - UInt32(UInt32(AValue) shr 31)) and
|
|
|
UInt32(Int32(0 - (Ord((AShiftBits and 31) <> 0) { and 1 } )))))
|
|
|
shl (32 - (AShiftBits and 31)))));
|
|
|
-{$ENDIF FPC}
|
|
|
+{$IFEND}
|
|
|
end;
|
|
|
|
|
|
-class function TBits.Asr64(AValue: Int64; AShiftBits: Byte): Int64;
|
|
|
+class function TBits.LeftShift32(AValue, AShiftBits: Int32): Int32;
|
|
|
begin
|
|
|
-{$IFDEF FPC}
|
|
|
- Result := SarInt64(AValue, AShiftBits);
|
|
|
-{$ELSE}
|
|
|
- Result := Int64(UInt64(UInt64(UInt64(AValue) shr (AShiftBits and 63)) or
|
|
|
- (UInt64(Int64(UInt64(0 - UInt64(UInt64(AValue) shr 63)) and
|
|
|
- UInt64(Int64(0 - (Ord((AShiftBits and 63) <> 0) { and 1 } )))))
|
|
|
- shl (64 - (AShiftBits and 63)))));
|
|
|
-{$ENDIF FPC}
|
|
|
+ Result := AValue shl (AShiftBits and 31);
|
|
|
+end;
|
|
|
+
|
|
|
+class function TBits.NegativeLeftShift32(AValue, AShiftBits: Int32): Int32;
|
|
|
+begin
|
|
|
+{$IFDEF DEBUG}
|
|
|
+ System.Assert(AShiftBits < 0);
|
|
|
+{$ENDIF DEBUG}
|
|
|
+ Result := AValue shl ((32 + AShiftBits) and 31);
|
|
|
end;
|
|
|
|
|
|
end.
|