mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-01 19:40:15 +02:00
+ another helper function: x86_parameterized_string_op_param_count
* when generating x86 code for parameterized string instructions with the internal object writer, don't rely on the destination operand being [(r/e)di] when determining the segment prefix, because when using intel syntax, source and destination can be anything (only the operand size, the address size and the source segment is taken into account) git-svn-id: trunk@37452 -
This commit is contained in:
parent
4c75b15afe
commit
baf492c7a5
@ -933,6 +933,9 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
{$ifdef x86}
|
||||
aasmcpu,
|
||||
{$endif x86}
|
||||
SysUtils,
|
||||
verbose,
|
||||
globals;
|
||||
@ -2603,6 +2606,10 @@ implementation
|
||||
|
||||
|
||||
procedure tai_cpu_abstract.loadref(opidx:longint;const r:treference);
|
||||
{$ifdef x86}
|
||||
var
|
||||
si_param: ShortInt;
|
||||
{$endif}
|
||||
begin
|
||||
allocate_oper(opidx+1);
|
||||
with oper[opidx]^ do
|
||||
@ -2619,9 +2626,10 @@ implementation
|
||||
too much of a a speed penalty}
|
||||
if is_x86_parameterized_string_op(opcode) then
|
||||
begin
|
||||
if ((ref^.base=NR_NO) or (getsupreg(ref^.base)<>RS_EDI)) and
|
||||
((ref^.index=NR_NO) or (getsupreg(ref^.index)<>RS_EDI)) and
|
||||
(ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||
si_param:=get_x86_string_op_si_param(opcode);
|
||||
if (si_param<>-1) and (taicpu(self).OperandOrder=op_att) then
|
||||
si_param:=x86_parameterized_string_op_param_count(opcode)-si_param-1;
|
||||
if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||
segprefix:=ref^.segment;
|
||||
end
|
||||
else if (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||
@ -2680,6 +2688,10 @@ implementation
|
||||
|
||||
|
||||
procedure tai_cpu_abstract.loadoper(opidx:longint;o:toper);
|
||||
{$ifdef x86}
|
||||
var
|
||||
si_param: ShortInt;
|
||||
{$endif x86}
|
||||
begin
|
||||
allocate_oper(opidx+1);
|
||||
clearop(opidx);
|
||||
@ -2698,11 +2710,14 @@ implementation
|
||||
new(ref);
|
||||
ref^:=o.ref^;
|
||||
{$ifdef x86}
|
||||
{ We allow this exception for x86, since overloading this would be
|
||||
too much of a a speed penalty}
|
||||
if is_x86_parameterized_string_op(opcode) then
|
||||
begin
|
||||
if ((ref^.base=NR_NO) or (getsupreg(ref^.base)<>RS_EDI)) and
|
||||
((ref^.index=NR_NO) or (getsupreg(ref^.index)<>RS_EDI)) and
|
||||
(ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||
si_param:=get_x86_string_op_si_param(opcode);
|
||||
if (si_param<>-1) and (taicpu(self).OperandOrder=op_att) then
|
||||
si_param:=x86_parameterized_string_op_param_count(opcode)-si_param-1;
|
||||
if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||
segprefix:=ref^.segment;
|
||||
end
|
||||
else if (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||
|
@ -468,6 +468,7 @@ interface
|
||||
{$ifdef i8086}
|
||||
procedure loadsegsymbol(opidx:longint;s:tasmsymbol);
|
||||
{$endif i8086}
|
||||
property OperandOrder : TOperandOrder read FOperandOrder;
|
||||
private
|
||||
{ next fields are filled in pass1, so pass2 is faster }
|
||||
insentry : PInsEntry;
|
||||
|
@ -323,6 +323,7 @@ uses
|
||||
{ checks whether the specified op is an x86 parameterized string instruction
|
||||
(e.g. returns true for movs, cmps, etc, but returns false for movsb, cmpsb, etc.) }
|
||||
function is_x86_parameterized_string_op(op: TAsmOp): boolean;
|
||||
function x86_parameterized_string_op_param_count(op: TAsmOp): shortint;
|
||||
function x86_param2paramless_string_op(op: TAsmOp): TAsmOp;
|
||||
function get_x86_string_op_size(op: TAsmOp): TOpSize;
|
||||
{ returns the 0-based operand number (intel syntax) of the ds:[si] param of
|
||||
@ -716,6 +717,19 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function x86_parameterized_string_op_param_count(op: TAsmOp): shortint;
|
||||
begin
|
||||
case op of
|
||||
A_MOVS,A_CMPS,A_INS,A_OUTS:
|
||||
result:=2;
|
||||
A_SCAS,A_LODS,A_STOS:
|
||||
result:=1;
|
||||
else
|
||||
internalerror(2017101203);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function x86_param2paramless_string_op(op: TAsmOp): TAsmOp;
|
||||
begin
|
||||
case op of
|
||||
|
Loading…
Reference in New Issue
Block a user