mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-07 09:59:39 +01:00
+ added x86 helper function get_default_segment_of_ref, which returns the
default segment base for the ref, in case there's no segment override * in the internal assembler, use get_default_segment_of_ref to strip redundant prefixes, instead of always assuming all refs are DS-based git-svn-id: trunk@37486 -
This commit is contained in:
parent
feb210cbc3
commit
67a0e9bdae
@ -2632,7 +2632,9 @@ implementation
|
|||||||
if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||||
segprefix:=ref^.segment;
|
segprefix:=ref^.segment;
|
||||||
end
|
end
|
||||||
else if (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
else if (opcode=A_XLAT) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||||
|
segprefix:=ref^.segment
|
||||||
|
else if (ref^.segment<>NR_NO) and (ref^.segment<>get_default_segment_of_ref(ref^)) then
|
||||||
segprefix:=ref^.segment;
|
segprefix:=ref^.segment;
|
||||||
{$endif}
|
{$endif}
|
||||||
{$ifndef llvm}
|
{$ifndef llvm}
|
||||||
@ -2720,7 +2722,9 @@ implementation
|
|||||||
if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
if (si_param=opidx) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||||
segprefix:=ref^.segment;
|
segprefix:=ref^.segment;
|
||||||
end
|
end
|
||||||
else if (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
else if (opcode=A_XLAT) and (ref^.segment<>NR_NO) and (ref^.segment<>NR_DS) then
|
||||||
|
segprefix:=ref^.segment
|
||||||
|
else if (ref^.segment<>NR_NO) and (ref^.segment<>get_default_segment_of_ref(ref^)) then
|
||||||
segprefix:=ref^.segment;
|
segprefix:=ref^.segment;
|
||||||
{$endif x86}
|
{$endif x86}
|
||||||
if assigned(add_reg_instruction_hook) then
|
if assigned(add_reg_instruction_hook) then
|
||||||
|
|||||||
@ -495,6 +495,7 @@ interface
|
|||||||
function is_32_bit_ref(const ref:treference):boolean;
|
function is_32_bit_ref(const ref:treference):boolean;
|
||||||
function is_16_bit_ref(const ref:treference):boolean;
|
function is_16_bit_ref(const ref:treference):boolean;
|
||||||
function get_ref_address_size(const ref:treference):byte;
|
function get_ref_address_size(const ref:treference):byte;
|
||||||
|
function get_default_segment_of_ref(const ref:treference):tregister;
|
||||||
|
|
||||||
function spilling_create_load(const ref:treference;r:tregister):Taicpu;
|
function spilling_create_load(const ref:treference;r:tregister):Taicpu;
|
||||||
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
||||||
@ -1849,6 +1850,24 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function get_default_segment_of_ref(const ref:treference):tregister;
|
||||||
|
begin
|
||||||
|
{ for 16-bit registers, we allow base and index to be swapped, that's
|
||||||
|
why we also we check whether ref.index=NR_BP. For 32-bit registers,
|
||||||
|
however, index=NR_EBP is encoded differently than base=NR_EBP and has
|
||||||
|
a different default segment. }
|
||||||
|
if (ref.base=NR_BP) or (ref.index=NR_BP) or
|
||||||
|
(ref.base=NR_EBP) or (ref.base=NR_ESP)
|
||||||
|
{$ifdef x86_64}
|
||||||
|
or (ref.base=NR_RBP) or (ref.base=NR_RSP)
|
||||||
|
{$endif x86_64}
|
||||||
|
then
|
||||||
|
result:=NR_SS
|
||||||
|
else
|
||||||
|
result:=NR_DS;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function taicpu.needaddrprefix(opidx:byte):boolean;
|
function taicpu.needaddrprefix(opidx:byte):boolean;
|
||||||
begin
|
begin
|
||||||
{$if defined(x86_64)}
|
{$if defined(x86_64)}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user