Componentes.Terceros.jcl/official/1.96/experts/debug/simdview/JclSIMDUtils.pas

915 lines
32 KiB
ObjectPascal

{**************************************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
{ License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
{ and limitations under the License. }
{ }
{ The Original Code is: JvSIMDUtils.pas, released on 2004-10-11. }
{ }
{ The Initial Developer of the Original Code is Florent Ouchet }
{ [ouchet dott florent att laposte dott net] }
{ Portions created by Florent Ouchet are Copyright (C) 2004 Florent Ouchet. }
{ All Rights Reserved. }
{ }
{ You may retrieve the latest version of this file at the Project JEDI's JCL home page, }
{ located at http://jcl.sourceforge.net }
{ }
{**************************************************************************************************}
// $Id: JclSIMDUtils.pas,v 1.6 2005/12/16 23:46:25 outchy Exp $
unit JclSIMDUtils;
{$I jcl.inc}
interface
uses
Windows,
ToolsAPI,
JclSysInfo,
JclOtaResources;
type
TJclMMContentType = (mt8Bytes, mt4Words, mt2DWords, mt1QWord, mt2Singles);
TJclMMRegister = packed record
case TJclMMContentType of
mt8Bytes:
(Bytes: array [0..7] of Byte;);
mt4Words:
(Words: array [0..3] of Word;);
mt2DWords:
(DWords: array [0..1] of Cardinal;);
mt1QWord:
(QWords: Int64;);
mt2Singles:
(Singles: array [0..1] of Single;);
end;
TJclFPUContentType = (ftExtended, ftMM);
TJclFPUData = packed record
case TJclFPUContentType of
ftExtended:
(FloatValue: Extended;);
ftMM:
(MMRegister: TJclMMRegister;
Reserved: Word;);
end;
TJclFPURegister = packed record
Data: TJclFPUData;
Reserved: array [0..5] of Byte;
end;
TJclFPURegisters = array [0..7] of TJclFPURegister;
TJclXMMContentType = (xt16Bytes, xt8Words, xt4DWords, xt2QWords, xt4Singles, xt2Doubles);
TJclXMMRegister = packed record
case TJclXMMContentType of
xt16Bytes:
(Bytes: array [0..15] of Byte;);
xt8Words:
(Words: array [0..7] of Word;);
xt4DWords:
(DWords: array [0..3] of Cardinal;);
xt2QWords:
(QWords: array [0..1] of Int64;);
xt4Singles:
(Singles: array [0..3] of Single;);
xt2Doubles:
(Doubles: array [0..1] of Double;);
end;
TJclProcessorSize = (ps32Bits, ps64Bits);
TJclXMMRegisters = packed record
case TJclProcessorSize of
ps32Bits:
(LegacyXMM: array [0..7] of TJclXMMRegister;
LegacyReserved: array [0..127] of Byte;);
ps64Bits:
(LongXMM: array [0..15] of TJclXMMRegister;);
end;
//TJclRoundingControl = (rcRoundToNearest, //=0
// rcRoundDown, //=1
// rcRoundUp, //=2
// rcRoundTowardZero); //=3
TJclVectorFrame = packed record
FCW: Word; // bytes from 0 to 1
FSW: Word; // bytes from 2 to 3
FTW: Byte; // byte 4
Reserved1: Byte; // byte 5
FOP: Word; // bytes from 6 to 7
FpuIp: Cardinal; // bytes from 8 to 11
CS: Word; // bytes from 12 to 13
Reserved2: Word; // bytes from 14 to 15
FpuDp: Cardinal; // bytes from 16 to 19
DS: Word; // bytes from 20 to 21
Reserved3: Word; // bytes from 22 to 23
MXCSR: Cardinal; // bytes from 24 to 27
MXCSRMask: Cardinal; // bytes from 28 to 31
FPURegisters: TJclFPURegisters; // bytes from 32 to 159
XMMRegisters: TJclXMMRegisters; // bytes from 160 to 415
Reserved4: array [416..511] of Byte; // bytes from 416 to 512
end;
TJclContext = packed record
ScalarContext: Windows.TContext;
VectorContext: TJclVectorFrame;
end;
PJclContext = ^TJclContext;
TBitDescription = record
AndMask: Cardinal;
Shifting: Cardinal;
ShortName: string;
LongName: string;
end;
TMXCSRRange = 0..14;
const
MXCSRBitsDescriptions: array [TMXCSRRange] of TBitDescription =
(
(AndMask: MXCSR_IE; Shifting: 0; ShortName: RsVectorIE; LongName: RsVectorIEText),
(AndMask: MXCSR_DE; Shifting: 1; ShortName: RsVectorDE; LongName: RsVectorDEText),
(AndMask: MXCSR_ZE; Shifting: 2; ShortName: RsVectorZE; LongName: RsVectorZEText),
(AndMask: MXCSR_OE; Shifting: 3; ShortName: RsVectorOE; LongName: RsVectorOEText),
(AndMask: MXCSR_UE; Shifting: 4; ShortName: RsVectorUE; LongName: RsVectorUEText),
(AndMask: MXCSR_PE; Shifting: 5; ShortName: RsVectorPE; LongName: RsVectorPEText),
(AndMask: MXCSR_DAZ; Shifting: 6; ShortName: RsVectorDAZ; LongName: RsVectorDAZText),
(AndMask: MXCSR_IM; Shifting: 7; ShortName: RsVectorIM; LongName: RsVectorIMText),
(AndMask: MXCSR_DM; Shifting: 8; ShortName: RsVectorDM; LongName: RsVectorDMText),
(AndMask: MXCSR_ZM; Shifting: 9; ShortName: RsVectorZM; LongName: RsVectorZMText),
(AndMask: MXCSR_OM; Shifting: 10; ShortName: RsVectorOM; LongName: RsVectorOMText),
(AndMask: MXCSR_UM; Shifting: 11; ShortName: RsVectorUM; LongName: RsVectorUMText),
(AndMask: MXCSR_PM; Shifting: 12; ShortName: RsVectorPM; LongName: RsVectorPMText),
(AndMask: MXCSR_RC; Shifting: 13; ShortName: RsVectorRC; LongName: RsVectorRCText),
(AndMask: MXCSR_FZ; Shifting: 15; ShortName: RsVectorFZ; LongName: RsVectorFZText)
);
type
TJclSIMDValue = packed record
case Display: TJclXMMContentType of
xt16Bytes:
(ValueByte: Byte;);
xt8Words:
(ValueWord: Word;);
xt4DWords:
(ValueDWord: Cardinal;);
xt2QWords:
(ValueQWord: Int64;);
xt4Singles:
(ValueSingle: Single;);
xt2Doubles:
(ValueDouble: Double;);
end;
TJclSIMDFormat = (sfBinary, sfSigned, sfUnsigned, sfHexa);
function FormatValue(Value: TJclSIMDValue; Format: TJclSIMDFormat): string;
function ParseValue(const StringValue: string; var Value: TJclSIMDValue;
Format: TJclSIMDFormat): Boolean;
function ReplaceSIMDRegisters(var Expression: string; Is64Bits: Boolean;
var VectorFrame: TJclVectorFrame): Boolean;
const
CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 or $00000020;
// return the processor frame for the specified thread, this thread must be suspended
function GetThreadContext(hThread: THandle; var lpContext: TJclContext): BOOL; stdcall;
// set the processor frame for the specified thread, this thread must be suspended
function SetThreadContext(hThread: THandle; const lpContext: TJclContext): BOOL; stdcall;
// return the XMM registers for the specified thread, this thread must be suspended
function GetVectorContext(AThread: IOTAThread; out VectorContext: TJclVectorFrame): Boolean;
// return the XMM registers for the specified thread, this thread must be suspended
function SetVectorContext(AThread: IOTAThread; const VectorContext: TJclVectorFrame): Boolean;
implementation
uses
SysUtils, Math,
JclOtaUtils;
function FormatBinary(Value: TJclSIMDValue): string;
var
I: Byte;
const
Width: array [xt16Bytes..xt2QWords] of Byte = (8, 16, 32, 64);
begin
if not (Value.Display in [xt16Bytes, xt8Words, xt4DWords, XT2QWords]) then
raise EJclExpertException.CreateTrace(RsEBadRegisterDisplay);
Assert(Value.Display < xt4Singles);
Result := StringOfChar('0', Width[Value.Display]);
for I := 1 to Width[Value.Display] do
begin
if (Value.ValueQWord and 1) <> 0 then
Result[Width[Value.Display] - I + 1] := '1';
Value.ValueQWord := Value.ValueQWord shr 1;
end;
end;
function FormatSigned(Value: TJclSIMDValue): string;
const
Width: array [xt16Bytes..xt2QWords] of Byte = (4, 6, 11, 20);
begin
if not (Value.Display in [xt16Bytes, xt8Words, xt4DWords, XT2QWords]) then
raise EJclExpertException.CreateTrace(RsEBadRegisterDisplay);
case Value.Display of
xt16Bytes:
Result := IntToStr(Shortint(Value.ValueByte));
xt8Words:
Result := IntToStr(Smallint(Value.ValueWord));
xt4DWords:
Result := IntToStr(Integer(Value.ValueDWord));
xt2QWords:
Result := IntToStr(Value.ValueQWord);
else
Result := '';
Exit;
end;
Result := StringOfChar(' ', Width[Value.Display] - Length(Result)) + Result;
end;
function FormatUnsigned(Value: TJclSIMDValue): string;
const
Width: array [xt16Bytes..xt2QWords] of Byte = (3, 5, 10, 20);
begin
if not (Value.Display in [xt16Bytes, xt8Words, xt4DWords, XT2QWords]) then
raise EJclExpertException.CreateTrace(RsEBadRegisterDisplay);
case Value.Display of
xt16Bytes:
Result := IntToStr(Byte(Value.ValueByte));
xt8Words:
Result := IntToStr(Word(Value.ValueWord));
xt4DWords:
Result := IntToStr(Cardinal(Value.ValueDWord));
xt2QWords:
Result := IntToStr(Value.ValueQWord);
else
Result := '';
Exit;
end;
Result := StringOfChar(' ', Width[Value.Display] - Length(Result)) + Result;
end;
function FormatHexa(Value: TJclSIMDValue): string;
const
Width: array [xt16Bytes..xt2QWords] of Byte = (2, 4, 8, 16);
begin
if not (Value.Display in [xt16Bytes, xt8Words, xt4DWords, XT2QWords]) then
raise EJclExpertException.CreateTrace(RsEBadRegisterDisplay);
case Value.Display of
xt16Bytes:
Result := IntToHex(Value.ValueByte, Width[xt16Bytes]);
xt8Words:
Result := IntToHex(Value.ValueWord, Width[xt8Words]);
xt4DWords:
Result := IntToHex(Value.ValueDWord, Width[xt4DWords]);
xt2QWords:
Result := IntToHex(Value.ValueQWord, Width[xt2QWords]);
else
Result := '';
end;
end;
function FormatFloat(Value: TJclSIMDValue): string;
begin
if not (Value.Display in [xt4Singles, xt2Doubles]) then
raise EJclExpertException.CreateTrace(RsEBadRegisterDisplay);
case Value.Display of
xt4Singles:
Result := FloatToStr(Value.ValueSingle);
xt2Doubles:
Result := FloatToStr(Value.ValueDouble);
else
Result := '';
end;
Result := StringOfChar(' ', 22 - Length(Result)) + Result; // 22 = max string length of a double value
end;
function FormatValue(Value: TJclSIMDValue; Format: TJclSIMDFormat): string;
type
TFormatFunction = function(Value: TJclSIMDValue): string;
var
FormatFunction: TFormatFunction;
begin
Result := '';
case Format of
sfBinary:
FormatFunction := FormatBinary;
sfSigned:
FormatFunction := FormatSigned;
sfUnsigned:
FormatFunction := FormatUnsigned;
sfHexa:
FormatFunction := FormatHexa;
else
Exit;
end;
case Value.Display of
xt16Bytes..xt2QWords:
Result := FormatFunction(Value);
xt4Singles..xt2Doubles:
Result := FormatFloat(Value);
end;
end;
function ParseBinary(StringValue: string; var Value: TJclSIMDValue): Boolean;
var
TestValue: Int64;
Index: Integer;
begin
TestValue := 0;
Result := False;
if Length(StringValue) > 64 then
Exit;
for Index := 1 to Length(StringValue) do
begin
TestValue := TestValue shl 1;
case StringValue[Index] of
'0':
;
'1':
Inc(TestValue);
else
Exit;
end;
end;
Result := True;
case Value.Display of
xt16Bytes:
if (TestValue >= Byte($00)) and (TestValue <= Byte($FF)) then
Value.ValueByte := TestValue
else
Result := False;
xt8Words:
if (TestValue >= Word($0000)) and (TestValue <= Word($FFFF)) then
Value.ValueWord := TestValue
else
Result := False;
xt4DWords:
if (TestValue >= Cardinal($00000000)) and (TestValue <= Cardinal($FFFFFFFF)) then
Value.ValueDWord := TestValue
else
Result := False;
xt2QWords:
Value.ValueQWord := TestValue;
else
Result := False;
end;
end;
function ParseSigned(StringValue: string; var Value: TJclSIMDValue): Boolean;
var
TestValue: Int64;
ErrorCode: Integer;
begin
Val(StringValue, TestValue, ErrorCode);
Result := ErrorCode = 0;
if Result then
case Value.Display of
xt16Bytes:
if (TestValue >= Shortint($80)) and (TestValue <= Shortint($7F)) then
Value.ValueByte := TestValue
else
Result := False;
xt8Words:
if (TestValue >= Smallint($8000)) and (TestValue <= Smallint($7FFF)) then
Value.ValueWord := TestValue
else
Result := False;
xt4DWords:
if (TestValue >= Integer($80000000)) and (TestValue <= Integer($7FFFFFFF)) then
Value.ValueDWord := TestValue
else
Result := False;
xt2QWords:
Value.ValueQWord := TestValue;
else
Result := False;
end;
end;
function ParseUnsigned(StringValue: string; var Value: TJclSIMDValue): Boolean;
var
TestValue: Int64;
ErrorCode: Integer;
begin
Val(StringValue, TestValue, ErrorCode);
Result := ErrorCode = 0;
if Result then
case Value.Display of
xt16Bytes:
if (TestValue >= Byte($00)) and (TestValue <= Byte($FF)) then
Value.ValueByte := TestValue
else
Result := False;
xt8Words:
if (TestValue >= Word($0000)) and (TestValue <= Word($FFFF)) then
Value.ValueWord := TestValue
else
Result := False;
xt4DWords:
if (TestValue >= Cardinal($00000000)) and (TestValue <= Cardinal($FFFFFFFF)) then
Value.ValueDWord := TestValue
else
Result := False;
xt2QWords:
Value.ValueQWord := TestValue;
else
Result := False;
end;
end;
function ParseHexa(StringValue: string; var Value: TJclSIMDValue): Boolean;
var
TestValue: Int64;
Index: Integer;
begin
TestValue := 0;
Result := False;
if Length(StringValue) > 16 then
Exit;
for Index := 1 to Length(StringValue) do
begin
TestValue := TestValue shl 4;
case StringValue[Index] of
'0':
;
'1'..'9':
Inc(TestValue, Ord(StringValue[Index]) - Ord('0'));
'A'..'F':
Inc(TestValue, Ord(StringValue[Index]) - Ord('A') + 10);
'a'..'f':
Inc(TestValue, Ord(StringValue[Index]) - Ord('a') + 10);
else
Exit;
end;
end;
Result := True;
case Value.Display of
xt16Bytes:
if (TestValue >= Byte($00)) and (TestValue <= Byte($FF)) then
Value.ValueByte := TestValue
else
Result := False;
xt8Words:
if (TestValue >= Word($0000)) and (TestValue <= Word($FFFF)) then
Value.ValueWord := TestValue
else
Result := False;
xt4DWords:
if (TestValue >= Cardinal($00000000)) and (TestValue <= Cardinal($FFFFFFFF)) then
Value.ValueDWord := TestValue
else
Result := False;
xt2QWords:
Value.ValueQWord := TestValue;
else
Result := False;
end;
end;
function ParseFloat(StringValue: string; var Value: TJclSIMDValue): Boolean;
var
TestValue: Extended;
ErrorCode: Integer;
begin
if DecimalSeparator <> '.' then
StringValue := StringReplace(StringValue, DecimalSeparator, '.', [rfReplaceAll, rfIgnoreCase]);
Val(StringValue, TestValue, ErrorCode);
Result := ErrorCode = 0;
if Result then
case Value.Display of
xt4Singles:
if (TestValue >= -MaxSingle) and (TestValue <= MaxSingle) then
Value.ValueSingle := TestValue
else
Result := False;
xt2Doubles:
if (TestValue >= MaxDouble) and (TestValue <= MaxDouble) then
Value.ValueDouble := TestValue
else
Result := False;
else
Result := False;
end;
end;
function ParseValue(const StringValue: string; var Value: TJclSIMDValue;
Format: TJclSIMDFormat): Boolean;
type
TParseFunction = function(StringValue: string; var Value: TJclSIMDValue): Boolean;
var
ParseFunction: TParseFunction;
begin
Result := False;
case Format of
sfBinary:
ParseFunction := ParseBinary;
sfSigned:
ParseFunction := ParseSigned;
sfUnsigned:
ParseFunction := ParseUnsigned;
sfHexa:
ParseFunction := ParseHexa;
else
Exit;
end;
case Value.Display of
xt16Bytes..xt2QWords:
Result := ParseFunction(StringValue, Value);
xt4Singles..xt2Doubles:
Result := ParseFloat(StringValue, Value);
end;
end;
function ReplaceSIMDRegisters(var Expression: string; Is64Bits: Boolean;
var VectorFrame: TJclVectorFrame): Boolean;
var
LocalString: string;
RegisterPosition: Integer;
DataPosition: Integer;
DataType: string;
Index: Integer;
RegisterIndex: Integer;
DataIndex: Integer;
ErrorCode: Integer;
NumberOfXMMRegister: Integer;
AValue: TJclSIMDValue;
ValueStr: string;
OldLength: Integer;
begin
if Is64Bits then
NumberOfXMMRegister := 16
else
NumberOfXMMRegister := 8;
Result := False;
LocalString := AnsiUpperCase(Expression);
RegisterPosition := AnsiPos('XMM', LocalString);
while (RegisterPosition > 0) do
begin
for Index := RegisterPosition to Length(LocalString) do
if LocalString[Index] = '.' then
Break;
if Index >= Length(LocalString) then
Exit;
Val(Copy(LocalString, RegisterPosition + 3, Index - RegisterPosition - 3), RegisterIndex, ErrorCode);
if (ErrorCode <> 0) or (RegisterIndex < 0) or (RegisterIndex >= NumberOfXMMRegister) then
Exit;
DataPosition := Index + 1;
if DataPosition > Length(LocalString) then
Exit;
for Index := DataPosition to Length(LocalString) do
if LocalString[Index] in ['0'..'9'] then
Break;
if Index > Length(LocalString) then
Exit;
DataType := Copy(LocalString, DataPosition, Index - DataPosition);
DataPosition := Index;
for Index := DataPosition to Length(LocalString) do
if not (LocalString[Index] in ['0'..'9']) then
Break;
Val(Copy(LocalString, DataPosition, Index - DataPosition), DataIndex, ErrorCode);
if (ErrorCode <> 0) or (DataIndex < 0) then
Exit;
if CompareStr(DataType, 'BYTE') = 0 then
begin
if DataIndex >= 16 then
Exit;
AValue.Display := xt16Bytes;
AValue.ValueByte := VectorFrame.XMMRegisters.LongXMM[RegisterIndex].Bytes[DataIndex];
end
else
if CompareStr(DataType, 'WORD') = 0 then
begin
if DataIndex >= 8 then
Exit;
AValue.Display := xt8Words;
AValue.ValueWord := VectorFrame.XMMRegisters.LongXMM[RegisterIndex].Words[DataIndex];
end
else
if CompareStr(DataType, 'DWORD') = 0 then
begin
if DataIndex >= 4 then
Exit;
AValue.Display := xt4DWords;
AValue.ValueDWord := VectorFrame.XMMRegisters.LongXMM[RegisterIndex].DWords[DataIndex];
end
else
if CompareStr(DataType, 'QWORD') = 0 then
begin
if DataIndex >= 2 then
Exit;
AValue.Display := xt2QWords;
AValue.ValueQWord := VectorFrame.XMMRegisters.LongXMM[RegisterIndex].QWords[DataIndex];
end
else
if CompareStr(DataType, 'SINGLE') = 0 then
begin
if DataIndex >= 4 then
Exit;
AValue.Display := xt4Singles;
AValue.ValueSingle := VectorFrame.XMMRegisters.LongXMM[RegisterIndex].Singles[DataIndex];
end
else
if CompareStr(DataType, 'DOUBLE') = 0 then
begin
if DataIndex >= 2 then
Exit;
AValue.Display := xt2Doubles;
AValue.ValueDouble := VectorFrame.XMMRegisters.LongXMM[RegisterIndex].Doubles[DataIndex];
end
else
Exit;
ValueStr := Trim(FormatValue(AValue, sfSigned));
if DecimalSeparator <> '.' then
ValueStr := StringReplace(ValueStr, DecimalSeparator, '.', [rfReplaceAll, rfIgnoreCase]);
if Length(ValueStr) >= Index - RegisterPosition then
begin
OldLength := Length(Expression);
SetLength(Expression, Length(Expression) + Length(ValueStr) - (Index - RegisterPosition));
if Length(ValueStr) > Index - RegisterPosition then
Move(Expression[Index], Expression[RegisterPosition + Length(ValueStr)], OldLength - Index + 1);
Move(ValueStr[1], Expression[RegisterPosition], Length(ValueStr));
end
else
begin
Move(ValueStr[1], Expression[RegisterPosition], Length(ValueStr));
Move(Expression[Index], Expression[RegisterPosition + Length(ValueStr)], Length(Expression) - Index + 1);
SetLength(Expression, Length(Expression) + Length(ValueStr) - (Index - RegisterPosition));
end;
LocalString := AnsiUpperCase(Expression);
RegisterPosition := AnsiPos('XMM', LocalString);
end;
RegisterPosition := AnsiPos('MM', LocalString);
while (RegisterPosition > 0) do
begin
for Index := RegisterPosition to Length(LocalString) do
if LocalString[Index] = '.' then
Break;
if Index >= Length(LocalString) then
Exit;
Val(Copy(LocalString, RegisterPosition + 2, Index - RegisterPosition - 2), RegisterIndex, ErrorCode);
if (ErrorCode <> 0) or (RegisterIndex < 0) or (RegisterIndex >= 8) then
Exit;
DataPosition := Index + 1;
if DataPosition > Length(LocalString) then
Exit;
for Index := DataPosition to Length(LocalString) do
if LocalString[Index] in ['0'..'9'] then
Break;
if Index > Length(LocalString) then
Exit;
DataType := Copy(LocalString, DataPosition, Index - DataPosition);
DataPosition := Index;
for Index := DataPosition to Length(LocalString) do
if not (LocalString[Index] in ['0'..'9']) then
Break;
Val(Copy(LocalString, DataPosition, Index - DataPosition), DataIndex, ErrorCode);
if (ErrorCode <> 0) or (DataIndex < 0) then
Exit;
if CompareStr(DataType, 'BYTE') = 0 then
begin
if DataIndex >= 8 then
Exit;
AValue.Display := xt16Bytes;
AValue.ValueByte := VectorFrame.FPURegisters[RegisterIndex].Data.MMRegister.Bytes[DataIndex];
end
else
if CompareStr(DataType, 'WORD') = 0 then
begin
if DataIndex >= 4 then
Exit;
AValue.Display := xt8Words;
AValue.ValueWord := VectorFrame.FPURegisters[RegisterIndex].Data.MMRegister.Words[DataIndex];
end
else
if CompareStr(DataType, 'DWORD') = 0 then
begin
if DataIndex >= 2 then
Exit;
AValue.Display := xt4DWords;
AValue.ValueDWord := VectorFrame.FPURegisters[RegisterIndex].Data.MMRegister.DWords[DataIndex];
end
else
if CompareStr(DataType, 'QWORD') = 0 then
begin
if DataIndex >= 1 then
Exit;
AValue.Display := xt2QWords;
AValue.ValueQWord := VectorFrame.FPURegisters[RegisterIndex].Data.MMRegister.QWords;
end
else
if CompareStr(DataType, 'SINGLE') = 0 then
begin
if DataIndex >= 2 then
Exit;
AValue.Display := xt4Singles;
AValue.ValueSingle := VectorFrame.FPURegisters[RegisterIndex].Data.MMRegister.Singles[DataIndex];
end
else
Exit;
ValueStr := Trim(FormatValue(AValue, sfSigned));
if DecimalSeparator <> '.' then
ValueStr := StringReplace(ValueStr, DecimalSeparator, '.', [rfReplaceAll, rfIgnoreCase]);
if Length(ValueStr) >= Index - RegisterPosition then
begin
OldLength := Length(Expression);
SetLength(Expression, Length(Expression) + Length(ValueStr) - (Index - RegisterPosition));
if Length(ValueStr) > Index - RegisterPosition then
Move(Expression[Index], Expression[RegisterPosition + Length(ValueStr)], OldLength - Index + 1);
Move(ValueStr[1], Expression[RegisterPosition], Length(ValueStr));
end
else
begin
Move(ValueStr[1], Expression[RegisterPosition], Length(ValueStr));
Move(Expression[Index], Expression[RegisterPosition + Length(ValueStr)], Length(Expression) - Index + 1);
SetLength(Expression, Length(Expression) + Length(ValueStr) - (Index - RegisterPosition));
end;
LocalString := AnsiUpperCase(Expression);
RegisterPosition := AnsiPos('MM', LocalString);
end;
Result := True;
end;
function GetThreadContext(hThread: THandle;
var lpContext: TJclContext): BOOL; stdcall; external kernel32 name 'GetThreadContext';
function SetThreadContext(hThread: THandle;
const lpContext: TJclContext): BOOL; stdcall; external kernel32 name 'SetThreadContext';
function GetVectorContext(AThread: IOTAThread; out VectorContext: TJclVectorFrame): Boolean;
{$IFDEF COMPILER9_UP}
var
OTAXMMRegs: TOTAXMMRegs;
OTAThreadContext: TOTAThreadContext;
begin
Result := AThread.GetOTAXMMRegisters(OTAXMMRegs);
if Result then
begin
VectorContext.MXCSR := OTAXMMRegs.MXCSR;
VectorContext.MXCSRMask := $FFFFFFFF;
Move(OTAXMMRegs,VectorContext.XMMRegisters, SizeOf(TOTAXMMReg) * 8);
OTAThreadContext := AThread.OTAThreadContext;
VectorContext.FCW := OTAThreadContext.FloatSave.ControlWord;
VectorContext.FSW := OTAThreadContext.FloatSave.StatusWord;
VectorContext.FTW := OTAThreadContext.FloatSave.TagWord;
Move(OTAThreadContext.FloatSave.RegisterArea[00],VectorContext.FPURegisters[0],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[10],VectorContext.FPURegisters[1],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[20],VectorContext.FPURegisters[2],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[30],VectorContext.FPURegisters[3],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[40],VectorContext.FPURegisters[4],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[50],VectorContext.FPURegisters[5],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[60],VectorContext.FPURegisters[6],SizeOf(Extended));
Move(OTAThreadContext.FloatSave.RegisterArea[70],VectorContext.FPURegisters[7],SizeOf(Extended));
end;
end;
{$ELSE COMPILER9_UP}
var
ContextMemory: Pointer;
JvContext: PJclContext;
begin
GetMem(ContextMemory, SizeOf(TJclContext) + 15);
try
if (Cardinal(ContextMemory) and 15) <> 0 then
JvContext := PJclContext((Cardinal(ContextMemory) + 16) and $FFFFFFF0)
else
JvContext := ContextMemory;
JvContext^.ScalarContext.ContextFlags := CONTEXT_EXTENDED_REGISTERS;
Result := GetThreadContext(AThread.Handle,JvContext^) and
((JvContext^.ScalarContext.ContextFlags and CONTEXT_EXTENDED_REGISTERS)<>0);
if Result then
VectorContext := JvContext^.VectorContext
else
FillChar(VectorContext, SizeOf(VectorContext), 0);
finally
FreeMem(ContextMemory);
end;
end;
{$ENDIF COMPILER9_UP}
function SetVectorContext(AThread: IOTAThread; const VectorContext: TJclVectorFrame): Boolean;
{$IFDEF COMPILER9_UP}
var
OTAXMMRegs: TOTAXMMRegs;
begin
Result := True;
try
OTAXMMRegs.MXCSR := VectorContext.MXCSR;
Move(VectorContext.XMMRegisters,OTAXMMRegs,SizeOf(TOTAXMMReg) * 8);
AThread.SetOTAXMMRegisters(OTAXMMRegs);
except
Result := False;
end;
end;
{$ELSE COMPILER9_UP}
// MM registers can not saved (changes are overriden by the Borland's debugger)
{const
CONTEXT_FLAGS = CONTEXT_CONTROL or CONTEXT_INTEGER or CONTEXT_SEGMENTS
or CONTEXT_FLOATING_POINT or CONTEXT_EXTENDED_REGISTERS;
var
ContextMemory: Pointer;
JvContext: PJclContext;
Index: Integer;
begin
GetMem(ContextMemory,SizeOf(TJclContext)+15);
try
if ((Cardinal(ContextMemory) and 15)<>0) then
JvContext := PJclContext((Cardinal(ContextMemory)+16) and $FFFFFFF0)
else
JvContext := ContextMemory;
JvContext^.ScalarContext.ContextFlags := CONTEXT_FLAGS;
Result := GetThreadContext(hThread,JvContext^) and
((JvContext^.ScalarContext.ContextFlags and CONTEXT_FLAGS) = CONTEXT_FLAGS);
if (Result) then
begin
JvContext^.ScalarContext.ContextFlags := CONTEXT_FLAGS;
JvContext^.VectorContext := VectorContext;
for Index := 0 to 7 do
Move(VectorContext.FPURegisters[Index].Data.FloatValue,JvContext^.ScalarContext.FloatSave.RegisterArea[Index*SizeOf(Extended)],SizeOf(Extended));
Result := SetThreadContext(hThread,JvContext^);
end;
finally
FreeMem(ContextMemory);
end;
end;}
var
ContextMemory: Pointer;
JvContext: PJclContext;
begin
GetMem(ContextMemory, SizeOf(TJclContext) + 15);
try
if (Cardinal(ContextMemory) and 15) <> 0 then
JvContext := PJclContext((Cardinal(ContextMemory) + 16) and $FFFFFFF0)
else
JvContext := ContextMemory;
JvContext^.ScalarContext.ContextFlags := CONTEXT_EXTENDED_REGISTERS;
Result := GetThreadContext(AThread.Handle,JvContext^) and
((JvContext^.ScalarContext.ContextFlags and CONTEXT_EXTENDED_REGISTERS) = CONTEXT_EXTENDED_REGISTERS);
if Result then
Result := SetThreadContext(AThread.Handle,JvContext^);
finally
FreeMem(ContextMemory);
end;
end;
{$ENDIF COMPILER9_UP}
// History:
// $Log: JclSIMDUtils.pas,v $
// Revision 1.6 2005/12/16 23:46:25 outchy
// Added expert stack form.
// Added code to display call stack on expert exception.
// Fixed package extension for D2006.
//
// Revision 1.5 2005/12/04 10:10:57 obones
// Borland Developer Studio 2006 support
//
// Revision 1.4 2005/11/21 21:25:40 outchy
// Modified the get/set methods of thread context for Delphi 2005
//
// Revision 1.3 2005/10/26 03:29:44 rrossmair
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and $Log: JclSIMDUtils.pas,v $
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and Revision 1.6 2005/12/16 23:46:25 outchy
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and Added expert stack form.
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and Added code to display call stack on expert exception.
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and Fixed package extension for D2006.
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and Revision 1.5 2005/12/04 10:10:57 obones
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and Borland Developer Studio 2006 support
// - improved header information, added $Date: 2005/12/16 23:46:25 $ and CVS tags.
//
end.