#97 add support for eflags reading

This commit is contained in:
Basile Burg 2016-09-29 09:48:35 +02:00
parent 7088cf0f54
commit b60c08b8a0
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
1 changed files with 64 additions and 9 deletions

View File

@ -32,14 +32,21 @@ type
{$ENDIF} {$ENDIF}
TFLAG = (CF, PF, AF, ZF, SF, TF, IF_, DF, OF_, NT, RF, VM, AC, VIF, VIP, ID); TFLAG = (CF, PF, AF, ZF, SF, TF, IF_, DF, OF_);
TEFLAG = set of TFLAG;
const FlagValues: array[TFlag] of word = (1, 4, 16, 64, 128, 256, 512, 1024, 2048);
type
TFLAGS = set of TFLAG;
TSegRegister = (CS, SS, DS, ES, FS, GS); TSegRegister = (CS, SS, DS, ES, FS, GS);
{$IFDEF CPU64} {$IFDEF CPU64}
const segOffset = 18; const segOffset = 18;
const flagOffset = 17;
{$ELSE} {$ELSE}
const segOffset = 10; const segOffset = 10;
const segOffset = 9;
{$ENDIF} {$ENDIF}
type type
@ -127,6 +134,8 @@ type
procedure setInspectableRegister(index: TSegRegister; value: TCPUSegValue); procedure setInspectableRegister(index: TSegRegister; value: TCPUSegValue);
end; end;
TSetFlagEvent = procedure(reg: TFlag; val: boolean) of object;
TSetFprEvent = procedure(reg: TFpuRegister; val: extended) of object; TSetFprEvent = procedure(reg: TFpuRegister; val: extended) of object;
// Makes a category for the floating point unit registers in a object inspector // Makes a category for the floating point unit registers in a object inspector
@ -176,20 +185,22 @@ type
// Stores the registers content, to be displayable in an object inspector. // Stores the registers content, to be displayable in an object inspector.
TInspectableCPU = class(TPersistent) TInspectableCPU = class(TPersistent)
private private
fFlags: TEFLAG; fFlags: TFlags;
fSetFlagEvent: TSetFlagEvent;
fGpr: TInspectableGPR; fGpr: TInspectableGPR;
fFpr: TInspectableFPR; fFpr: TInspectableFPR;
fSsr: TInspectableSSR; fSsr: TInspectableSSR;
procedure setFlag(value: TFlags);
published published
property CPU: TInspectableGPR read fGpr; property CPU: TInspectableGPR read fGpr;
property FPU: TInspectableFPR read fFpr; property FPU: TInspectableFPR read fFpr;
property SSR: TInspectableSSR read fSsr; property SSR: TInspectableSSR read fSsr;
// property FLAGS: TFlags read fFlags write setFlag;
property EFLAGS: TEFLAG read fFlags;
public public
constructor create(setGprEvent: TSetGprEvent; setSsrEvent: TSetSsrEvent; constructor create(setGprEvent: TSetGprEvent; setSsrEvent: TSetSsrEvent;
setFprEvent: TSetFprEvent); setFlagEvent: TSetFlagEvent; setFprEvent: TSetFprEvent);
destructor destroy; override; destructor destroy; override;
procedure setInspectableFlags(value: word);
end; end;
// Represents an item in the call stack // Represents an item in the call stack
@ -360,6 +371,7 @@ type
procedure setGpr(reg: TCpuRegister; val: TCpuGprValue); procedure setGpr(reg: TCpuRegister; val: TCpuGprValue);
procedure setFpr(reg: TFpuRegister; val: extended); procedure setFpr(reg: TFpuRegister; val: extended);
procedure setSsr(reg: TSegRegister; val: TCPUSegValue); procedure setSsr(reg: TSegRegister; val: TCPUSegValue);
procedure setFlag(reg: TFLAG; val: boolean);
// //
procedure projNew(project: ICECommonProject); procedure projNew(project: ICECommonProject);
procedure projChanged(project: ICECommonProject); procedure projChanged(project: ICECommonProject);
@ -746,8 +758,9 @@ begin
end; end;
constructor TInspectableCPU.create(setGprEvent: TSetGprEvent; setSsrEvent: TSetSsrEvent; constructor TInspectableCPU.create(setGprEvent: TSetGprEvent; setSsrEvent: TSetSsrEvent;
setFprEvent: TSetFprEvent); setFlagEvent: TSetFlagEvent; setFprEvent: TSetFprEvent);
begin begin
fSetFlagEvent:=setFlagEvent;
fGpr := TInspectableGPR.create(setGprEvent); fGpr := TInspectableGPR.create(setGprEvent);
fSsr := TInspectableSSR.create(setSsrEvent); fSsr := TInspectableSSR.create(setSsrEvent);
fFpr := TInspectableFPR.create(setFprEvent); fFpr := TInspectableFPR.create(setFprEvent);
@ -760,6 +773,30 @@ begin
fSSr.Free; fSSr.Free;
inherited; inherited;
end; end;
procedure TInspectableCPU.setInspectableFlags(value: word);
var
flg: TFlag;
begin
fFlags:= [];
for flg in TFlag do
if (value and FlagValues[flg]) >= FlagValues[flg] then
fFlags += [flg];
end;
procedure TInspectableCPU.setFlag(value: TFlags);
var
flg: TFlag;
begin
if fFlags = value then
exit;
for flg in TFlag do
begin
if (flg in value) <> (flg in fFlags) then
fSetFlagEvent(flg, flg in value);
end;
fFlags := value;
end;
{$ENDREGION} {$ENDREGION}
{$REGION Common/standard comp --------------------------------------------------} {$REGION Common/standard comp --------------------------------------------------}
@ -772,7 +809,7 @@ begin
fMsg:= getMessageDisplay; fMsg:= getMessageDisplay;
fFileLineBrks:= TStringList.Create; fFileLineBrks:= TStringList.Create;
fLog := TStringList.Create; fLog := TStringList.Create;
fInspState := TInspectableCPU.Create(@setGpr, @setSsr, @setFpr); fInspState := TInspectableCPU.Create(@setGpr, @setSsr, @setFlag, @setFpr);
stateViewer.TIObject := fInspState; stateViewer.TIObject := fInspState;
fJson := TJsonObject.Create; fJson := TJsonObject.Create;
fStackItems := TStackItems.create; fStackItems := TStackItems.create;
@ -1578,6 +1615,10 @@ begin
fInspState.CPU.setInspectableRegister fInspState.CPU.setInspectableRegister
(TCpuRegister(number), {$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF}); (TCpuRegister(number), {$IFDEF CPU64}val.AsInt64{$ELSE}val.AsInteger{$ENDIF});
end; end;
flagOffset:
begin
fInspState.setInspectableFlags(word(val.AsInteger));
end;
segOffset..segOffset+5: segOffset..segOffset+5:
begin begin
fInspState.SSR.setInspectableRegister fInspState.SSR.setInspectableRegister
@ -1657,7 +1698,7 @@ begin
val := obj.Find('value'); val := obj.Find('value');
if val.isNil then if val.isNil then
continue; continue;
ValueListEditor1.InsertRow(nme, val.AsString, true); ValueListEditor1.InsertRow(nme, val.AsString, false);
end; end;
end; end;
@ -1842,6 +1883,20 @@ begin
gdbCommand(cmd); gdbCommand(cmd);
end; end;
procedure TCEGdbWidget.setFlag(reg: TFLAG; val: boolean);
const
// TODO-cGDB: set eflags from expr fails with "invalid cast"
spec: array[boolean] of string = (
'set $eflags &= ~0x%X',
'set $eflags |= 0x%X'
);
var
cmd: string;
begin
cmd := format(spec[val], [FlagValues[reg]]);
gdbCommand(cmd);
end;
procedure TCEGdbWidget.setFpr(reg: TFpuRegister; val: extended); procedure TCEGdbWidget.setFpr(reg: TFpuRegister; val: extended);
const const
spec = 'set $%s = %.18g'; spec = 'set $%s = %.18g';