* changed the x86 TInsProp.Ch structure from a 3-element array to a pascal set;

this removes the limit of 3 Ch_XXX flags per instruction (thus allowing adding
  more precise flags, e.g. for tracking only certain bits of the flags register,
  etc.) and avoids the ugliness of having the Ch_None filler, which makes
  x86ins.dat less readable.

git-svn-id: trunk@35850 -
This commit is contained in:
nickysn 2017-04-19 16:48:35 +00:00
parent 189e49998c
commit 9303a8f61a
7 changed files with 4090 additions and 4059 deletions

View File

@ -181,37 +181,77 @@ unit aoptcpu;
RegReadByInstruction := true;
exit
end;
for opcount := 1 to maxinschanges do
case insprop[p.opcode].ch[opcount] of
CH_REAX..CH_REDI,CH_RWEAX..CH_MEDI:
if getsupreg(reg) = tch2reg(insprop[p.opcode].ch[opcount]) then
begin
RegReadByInstruction := true;
exit
end;
CH_RWOP1,CH_ROP1,CH_MOP1:
if reginop(reg,p.oper[0]^) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOP2,Ch_ROP2,Ch_MOP2:
if reginop(reg,p.oper[1]^) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOP3,Ch_ROP3,Ch_MOP3:
if reginop(reg,p.oper[2]^) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RFlags,Ch_RWFlags:
if reg=NR_DEFAULTFLAGS then
begin
RegReadByInstruction := true;
exit
with insprop[p.opcode] do
begin
case getsupreg(reg) of
RS_EAX:
if [Ch_REAX,Ch_RWEAX,Ch_MEAX]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_ECX:
if [Ch_RECX,Ch_RWECX,Ch_MECX]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_EDX:
if [Ch_REDX,Ch_RWEDX,Ch_MEDX]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_EBX:
if [Ch_REBX,Ch_RWEBX,Ch_MEBX]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_ESP:
if [Ch_RESP,Ch_RWESP,Ch_MESP]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_EBP:
if [Ch_REBP,Ch_RWEBP,Ch_MEBP]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_ESI:
if [Ch_RESI,Ch_RWESI,Ch_MESI]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
RS_EDI:
if [Ch_REDI,Ch_RWEDI,Ch_MEDI]*Ch<>[] then
begin
RegReadByInstruction := true;
exit
end;
end;
if ([CH_RWOP1,CH_ROP1,CH_MOP1]*Ch<>[]) and reginop(reg,p.oper[0]^) then
begin
RegReadByInstruction := true;
exit
end;
if ([Ch_RWOP2,Ch_ROP2,Ch_MOP2]*Ch<>[]) and reginop(reg,p.oper[1]^) then
begin
RegReadByInstruction := true;
exit
end;
if ([Ch_RWOP3,Ch_ROP3,Ch_MOP3]*Ch<>[]) and reginop(reg,p.oper[2]^) then
begin
RegReadByInstruction := true;
exit
end;
if ([Ch_RFlags,Ch_RWFlags]*Ch<>[]) and (reg=NR_DEFAULTFLAGS) then
begin
RegReadByInstruction := true;
exit
end;
end;
end;
@ -240,11 +280,8 @@ function InstrReadsFlags(p: tai): boolean;
InstrReadsFlags := true;
case p.typ of
ait_instruction:
begin
for l := 1 to maxinschanges do
if InsProp[taicpu(p).opcode].Ch[l] in [Ch_RFlags,Ch_RWFlags,Ch_All] then
exit;
end;
if InsProp[taicpu(p).opcode].Ch*[Ch_RFlags,Ch_RWFlags,Ch_All]<>[] then
exit;
ait_label:
exit;
end;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -348,6 +348,8 @@ begin
repeat
readln(infile,inschanges);
until eof(infile) or ((inschanges<>'') and (inschanges[1]<>';'));
inschanges[1]:='[';
inschanges[length(inschanges)]:=']';
continue;
end;
{ we must have an opcode }

View File

@ -196,7 +196,6 @@ interface
instabentries = {$i i8086nop.inc}
{$endif}
maxinfolen = 8;
MaxInsChanges = 3; { Max things a instruction can change }
type
{ What an instruction can change. Needed for optimizer and spilling code.
@ -228,7 +227,7 @@ interface
);
TInsProp = packed record
Ch : Array[1..MaxInsChanges] of TInsChange;
Ch : set of TInsChange;
end;
TMemRefSizeInfo = (msiUnkown, msiUnsupported, msiNoSize,
@ -3474,34 +3473,27 @@ implementation
new(operation_type_table);
fillchar(operation_type_table^,sizeof(toperation_type_table),byte(operand_read));
for opcode:=low(tasmop) to high(tasmop) do
begin
for i:=1 to MaxInsChanges do
begin
case InsProp[opcode].Ch[i] of
Ch_Rop1 :
operation_type_table^[opcode,0]:=operand_read;
Ch_Wop1 :
operation_type_table^[opcode,0]:=operand_write;
Ch_RWop1,
Ch_Mop1 :
operation_type_table^[opcode,0]:=operand_readwrite;
Ch_Rop2 :
operation_type_table^[opcode,1]:=operand_read;
Ch_Wop2 :
operation_type_table^[opcode,1]:=operand_write;
Ch_RWop2,
Ch_Mop2 :
operation_type_table^[opcode,1]:=operand_readwrite;
Ch_Rop3 :
operation_type_table^[opcode,2]:=operand_read;
Ch_Wop3 :
operation_type_table^[opcode,2]:=operand_write;
Ch_RWop3,
Ch_Mop3 :
operation_type_table^[opcode,2]:=operand_readwrite;
end;
end;
end;
with InsProp[opcode] do
begin
if Ch_Rop1 in Ch then
operation_type_table^[opcode,0]:=operand_read;
if Ch_Wop1 in Ch then
operation_type_table^[opcode,0]:=operand_write;
if [Ch_RWop1,Ch_Mop1]*Ch<>[] then
operation_type_table^[opcode,0]:=operand_readwrite;
if Ch_Rop2 in Ch then
operation_type_table^[opcode,1]:=operand_read;
if Ch_Wop2 in Ch then
operation_type_table^[opcode,1]:=operand_write;
if [Ch_RWop2,Ch_Mop2]*Ch<>[] then
operation_type_table^[opcode,1]:=operand_readwrite;
if Ch_Rop3 in Ch then
operation_type_table^[opcode,2]:=operand_read;
if Ch_Wop3 in Ch then
operation_type_table^[opcode,2]:=operand_write;
if [Ch_RWop3,Ch_Mop3]*Ch<>[] then
operation_type_table^[opcode,2]:=operand_readwrite;
end;
end;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff