#97, add support for the FPU

This commit is contained in:
Basile Burg 2016-09-28 22:14:02 +02:00
parent 6daf51bb9c
commit b8f0338c18
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
1 changed files with 97 additions and 35 deletions

View File

@ -17,13 +17,22 @@ type
{$IFDEF CPU64} {$IFDEF CPU64}
TCpuRegister = (rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13, TCpuRegister = (rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8, r9, r10, r11, r12, r13,
r14, r15, rip); r14, r15, rip);
const stOffset = 24;
type
TFpuRegister = (st0, st1, st2, st3, st4, st5, st6, st7);
{$ENDIF} {$ENDIF}
{$IFDEF CPU32} {$IFDEF CPU32}
TCpuRegister = (eax, ebx, ecx, edx, esi, edi, ebp, esp, eip); TCpuRegister = (eax, ebx, ecx, edx, esi, edi, ebp, esp, eip);
const stOffset = 16;
type
TFpuRegister = (st0, st1, st2, st3, st4, st5, st6, st7);
{$ENDIF} {$ENDIF}
TFpuRegister = (st0, st1, st2, st3, st4, st5, st6, st7);
TFLAG = (CS, PF, AF, ZF, SF, TF, IF_, DF, OF_, NT, RF, VM, AC, VIF, VIP, ID); TFLAG = (CS, PF, AF, ZF, SF, TF, IF_, DF, OF_, NT, RF, VM, AC, VIF, VIP, ID);
TEFLAG = set of TFLAG; TEFLAG = set of TFLAG;
@ -79,25 +88,30 @@ type
property EIP: TCpuRegValue index TCpuRegister.eip read fRegisters[TCpuRegister.eip] write setRegister; property EIP: TCpuRegValue index TCpuRegister.eip read fRegisters[TCpuRegister.eip] write setRegister;
{$ENDIF} {$ENDIF}
public public
constructor create(event: TSetGprEvent); constructor create(eventGPR: TSetGprEvent);
procedure setInspectableRegister(index: TCpuRegister; value: PtrUInt); procedure setInspectableRegister(index: TCpuRegister; value: PtrUInt);
end; end;
// Makes a category for the floating point coprocessor registers in a object inspector TSetFprEvent = procedure(reg: TFpuRegister; val: extended) of object;
// Makes a category for the floating point unit registers in a object inspector
TInspectableFPR = class(TPersistent) TInspectableFPR = class(TPersistent)
private private
fRegisters: array[TFpuRegister] of double; fRegisters: array[TFpuRegister] of extended;
fSetFprEvent: TSetFprEvent;
procedure setRegister(index: TFpuRegister; value: extended);
published published
property ST0: double read fRegisters[TFpuRegister.st0]; property ST0: extended index TFpuRegister.st0 read fRegisters[TFpuRegister.st0] write setRegister;
property ST1: double read fRegisters[TFpuRegister.st1]; property ST1: extended index TFpuRegister.st1 read fRegisters[TFpuRegister.st1] write setRegister;
property ST2: double read fRegisters[TFpuRegister.st2]; property ST2: extended index TFpuRegister.st2 read fRegisters[TFpuRegister.st2] write setRegister;
property ST3: double read fRegisters[TFpuRegister.st3]; property ST3: extended index TFpuRegister.st3 read fRegisters[TFpuRegister.st3] write setRegister;
property ST4: double read fRegisters[TFpuRegister.st4]; property ST4: extended index TFpuRegister.st4 read fRegisters[TFpuRegister.st4] write setRegister;
property ST5: double read fRegisters[TFpuRegister.st5]; property ST5: extended index TFpuRegister.st5 read fRegisters[TFpuRegister.st5] write setRegister;
property ST6: double read fRegisters[TFpuRegister.st6]; property ST6: extended index TFpuRegister.st6 read fRegisters[TFpuRegister.st6] write setRegister;
property ST7: double read fRegisters[TFpuRegister.st7]; property ST7: extended index TFpuRegister.st7 read fRegisters[TFpuRegister.st7] write setRegister;
public public
procedure setInspectableRegister(index: TFpuRegister; value: double); constructor create(event: TSetFprEvent);
procedure setInspectableRegister(index: TFpuRegister; value: extended);
end; end;
// Makes a category for the SSE registers in a object inspector // Makes a category for the SSE registers in a object inspector
@ -106,7 +120,6 @@ type
// 4 int ? 2 double ? 4 single ? ... // 4 int ? 2 double ? 4 single ? ...
end; end;
// Makes a category for the local variables in an object inspector // Makes a category for the local variables in an object inspector
TInspectableLocals= class(TPersistent) TInspectableLocals= class(TPersistent)
private private
@ -136,17 +149,18 @@ type
published published
property Locals: TInspectableLocals read fLocals; property Locals: TInspectableLocals read fLocals;
property CPU: TInspectableGPR read fGpr; property CPU: TInspectableGPR read fGpr;
property FPU: TInspectableFPR read fFpr;
// //
property EFLAGS: TEFLAG read fFlags; property EFLAGS: TEFLAG read fFlags;
// //
property CS: byte read fSegment[TSegmentRegister.S_CS]; (*property CS: byte read fSegment[TSegmentRegister.S_CS];
property DS: byte read fSegment[TSegmentRegister.S_DS]; property DS: byte read fSegment[TSegmentRegister.S_DS];
property ES: byte read fSegment[TSegmentRegister.S_ES]; property ES: byte read fSegment[TSegmentRegister.S_ES];
property FS: byte read fSegment[TSegmentRegister.S_FS]; property FS: byte read fSegment[TSegmentRegister.S_FS];
property GS: byte read fSegment[TSegmentRegister.S_GS]; property GS: byte read fSegment[TSegmentRegister.S_GS];
property SS: byte read fSegment[TSegmentRegister.S_SS]; property SS: byte read fSegment[TSegmentRegister.S_SS];*)
public public
constructor create(setGprEvent: TSetGprEvent); constructor create(setGprEvent: TSetGprEvent; setFprEvent: TSetFprEvent);
destructor destroy; override; destructor destroy; override;
end; end;
@ -299,6 +313,7 @@ type
procedure menuDeclare(item: TMenuItem); procedure menuDeclare(item: TMenuItem);
procedure menuUpdate(item: TMenuItem); procedure menuUpdate(item: TMenuItem);
// //
procedure disableEditor;
procedure setState(value: TGdbState); procedure setState(value: TGdbState);
procedure updateButtonsState; procedure updateButtonsState;
procedure startDebugging; procedure startDebugging;
@ -315,6 +330,7 @@ type
procedure infoVariables; procedure infoVariables;
procedure sendCustomCommand; procedure sendCustomCommand;
procedure setGpr(reg: TCpuRegister; val: TCpuRegValue); procedure setGpr(reg: TCpuRegister; val: TCpuRegValue);
procedure setFpr(reg: TFpuRegister; val: extended);
// //
procedure projNew(project: ICECommonProject); procedure projNew(project: ICECommonProject);
procedure projChanged(project: ICECommonProject); procedure projChanged(project: ICECommonProject);
@ -592,9 +608,9 @@ begin
end; end;
end; end;
constructor TInspectableGPR.create(event: TSetGprEvent); constructor TInspectableGPR.create(eventGPR: TSetGprEvent);
begin begin
fSetGprEvent:=event; fSetGprEvent:=eventGPR;
end; end;
procedure TInspectableGPR.setInspectableRegister(index: TCpuRegister; value: PtrUInt); procedure TInspectableGPR.setInspectableRegister(index: TCpuRegister; value: PtrUInt);
@ -608,8 +624,19 @@ begin
fRegisters[index] := value; fRegisters[index] := value;
end; end;
procedure TInspectableFPR.setInspectableRegister(index: TFpuRegister; value: double); constructor TInspectableFPR.create(event: TSetFprEvent);
begin begin
fSetFprEvent:=event;
end;
procedure TInspectableFPR.setInspectableRegister(index: TFpuRegister; value: extended);
begin
fRegisters[index] := value;
end;
procedure TInspectableFPR.setRegister(index: TFpuRegister; value: extended);
begin
fSetFprEvent(index, value);
fRegisters[index] := value; fRegisters[index] := value;
end; end;
@ -660,15 +687,17 @@ begin
fLocals.Values[name] := value; fLocals.Values[name] := value;
end; end;
constructor TInspectableState.create(setGprEvent: TSetGprEvent); constructor TInspectableState.create(setGprEvent: TSetGprEvent; setFprEvent: TSetFprEvent);
begin begin
fGpr := TInspectableGPR.Create(setGprEvent); fGpr := TInspectableGPR.create(setGprEvent);
fFpr := TInspectableFPR.create(setFprEvent);
fLocals := TInspectableLocals.create; fLocals := TInspectableLocals.create;
end; end;
destructor TInspectableState.destroy; destructor TInspectableState.destroy;
begin begin
fGpr.Free; fGpr.Free;
fFPr.Free;
fLocals.Free; fLocals.Free;
inherited; inherited;
end; end;
@ -684,14 +713,14 @@ begin
fMsg:= getMessageDisplay; fMsg:= getMessageDisplay;
fFileLineBrks:= TStringList.Create; fFileLineBrks:= TStringList.Create;
fLog := TStringList.Create; fLog := TStringList.Create;
fInspState := TInspectableState.Create(@setGpr); fInspState := TInspectableState.Create(@setGpr, @setFpr);
stateViewer.TIObject := fInspState; stateViewer.TIObject := fInspState;
fJson := TJsonObject.Create; fJson := TJsonObject.Create;
fStackItems := TStackItems.create; fStackItems := TStackItems.create;
fSubj:= TCEDebugObserverSubject.Create; fSubj:= TCEDebugObserverSubject.Create;
fOptions:= TCEDebugOptions.create(self); fOptions:= TCEDebugOptions.create(self);
Edit1.Items.Assign(fOptions.commandsHistory);
fOptions.onChangesApplied:=@optionsChangesApplied; fOptions.onChangesApplied:=@optionsChangesApplied;
Edit1.Items.Assign(fOptions.commandsHistory);
// //
AssignPng(btnSendCom, 'ACCEPT'); AssignPng(btnSendCom, 'ACCEPT');
setState(gsNone); setState(gsNone);
@ -1046,6 +1075,11 @@ begin
end; end;
end; end;
procedure TCEGdbWidget.disableEditor;
begin
stateViewer.ItemIndex:=-1;
end;
procedure TCEGdbWidget.startDebugging; procedure TCEGdbWidget.startDebugging;
var var
str: string; str: string;
@ -1366,6 +1400,9 @@ var
sigmean: string; sigmean: string;
signame: string; signame: string;
brkreason: TCEDebugBreakReason; brkreason: TCEDebugBreakReason;
// FPU
fFpuExtended: extended;
fFpuRaw: array[0..9] of Byte absolute fFpuExtended;
begin begin
val := fJson.Find('reason'); val := fJson.Find('reason');
@ -1478,19 +1515,34 @@ begin
if val.isNotNil then if val.isNotNil then
number := val.AsInteger; number := val.AsInteger;
val := obj.Find('value'); val := obj.Find('value');
if val.isNotNil then if val.isNotNil then case number of
0..integer(high(TCpuRegister)):
begin begin
if (0 <= number) and (TCpuRegister(number) <= high(TCpuRegister)) then fInspState.CPU.setInspectableRegister
fInspState.CPU.setInspectableRegister(TCpuRegister(number), (TCpuRegister(number), {$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF});
{$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF});
end; end;
stOffset..stOffset+7:
begin
//else fFpuRaw[9] := StrToInt('$' + val.AsString[3..4]);
// TODO-cGDB: FPU and SSE regs are in a sub object fFpuRaw[8] := StrToInt('$' + val.AsString[5..6]);
// break; fFpuRaw[7] := StrToInt('$' + val.AsString[7..8]);
fFpuRaw[6] := StrToInt('$' + val.AsString[9..10]);
fFpuRaw[5] := StrToInt('$' + val.AsString[11..12]);
fFpuRaw[4] := StrToInt('$' + val.AsString[13..14]);
fFpuRaw[3] := StrToInt('$' + val.AsString[15..16]);
fFpuRaw[2] := StrToInt('$' + val.AsString[17..18]);
fFpuRaw[1] := StrToInt('$' + val.AsString[19..20]);
fFpuRaw[0] := StrToInt('$' + val.AsString[21..22]);
fInspState.FPU.setInspectableRegister
(TFpuRegister(number - stOffset), fFpuExtended);
end; end;
end; end;
// TODO-cGDB: get SSE registers
// TODO-cGDB: get Segment registers
// TODO-cGDB: get EFLAGS
end;
end;
stateViewer.RefreshPropertyValues;
end; end;
val := fJson.Find('stack'); val := fJson.Find('stack');
@ -1619,7 +1671,8 @@ end;
procedure TCEGdbWidget.infoRegs; procedure TCEGdbWidget.infoRegs;
begin begin
gdbCommand('-data-list-register-values d', @gdboutJsonize); disableEditor;
gdbCommand('-data-list-register-values r', @gdboutJsonize);
end; end;
procedure TCEGdbWidget.infoStack; procedure TCEGdbWidget.infoStack;
@ -1721,6 +1774,15 @@ begin
gdbCommand(cmd); gdbCommand(cmd);
end; end;
procedure TCEGdbWidget.setFpr(reg: TFpuRegister; val: extended);
const
spec = 'set $%s = %.18g';
var
cmd : string;
begin
cmd := format(spec, [GetEnumName(typeinfo(TFpuRegister),integer(reg)), val]);
gdbCommand(cmd);
end;
{$ENDREGION} {$ENDREGION}
initialization initialization