mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-29 04:19:31 +02:00
Merged revision(s) 42176, 42186 from trunk:
* fixed an i8086 inline assembler bug, where 'call word ptr [label]' (an indirect call) was assembled as 'call near label' (direct call) instead of 'call near [label]' and 'call dword ptr [label]' was assembled as 'call near label' instead of 'call far [label]' ........ Add {$goto on} if FPC macro is defined ........ git-svn-id: branches/fixes_3_2@42215 -
This commit is contained in:
parent
783273cf01
commit
cfa1ddb5e4
@ -2686,7 +2686,8 @@ Unit Rax86int;
|
||||
{ convert 'call/jmp [proc/label]' to 'call/jmp proc/label'. Ugly,
|
||||
but Turbo Pascal 7 compatible. }
|
||||
if (instr.opcode in [A_CALL,A_JMP]) and
|
||||
(instr.operands[i].haslabelref or instr.operands[i].hasproc)
|
||||
(instr.operands[i].haslabelref or instr.operands[i].hasproc) and
|
||||
(not instr.operands[i].hastype)
|
||||
and (typ=OPR_REFERENCE) and
|
||||
assigned(ref.symbol) and (ref.symbol.typ in [AT_FUNCTION,AT_LABEL,AT_ADDR]) and
|
||||
(ref.base=NR_NO) and (ref.index=NR_NO) then
|
||||
|
@ -12,6 +12,11 @@
|
||||
|
||||
program tfarcal2;
|
||||
|
||||
{$ifdef FPC}
|
||||
{ FPC needs $goto on to accept labels and gotos }
|
||||
{$goto on}
|
||||
{$endif}
|
||||
|
||||
uses
|
||||
dos;
|
||||
|
||||
@ -24,9 +29,16 @@ const
|
||||
NearInt = $E7;
|
||||
FarInt = $E8;
|
||||
|
||||
NoSegOverride = 0;
|
||||
SegOverrideCS = $2E;
|
||||
SegOverrideSS = $36;
|
||||
SegOverrideDS = $3E;
|
||||
SegOverrideES = $26;
|
||||
|
||||
var
|
||||
OldNearIntVec: FarPointer;
|
||||
OldFarIntVec: FarPointer;
|
||||
ExpectSegOverride: Byte;
|
||||
|
||||
procedure Error;
|
||||
begin
|
||||
@ -40,6 +52,12 @@ procedure IntNearHandler(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word
|
||||
var
|
||||
modrm: Byte;
|
||||
begin
|
||||
if ExpectSegOverride <> 0 then
|
||||
begin
|
||||
if Mem[CS:IP]<>ExpectSegOverride then
|
||||
Error;
|
||||
Inc(IP);
|
||||
end;
|
||||
if Mem[CS:IP]<>$FF then
|
||||
Error;
|
||||
Inc(IP);
|
||||
@ -64,6 +82,12 @@ procedure IntFarHandler(Flags, CS, IP, AX, BX, CX, DX, SI, DI, DS, ES, BP: Word)
|
||||
var
|
||||
modrm: Byte;
|
||||
begin
|
||||
if ExpectSegOverride <> 0 then
|
||||
begin
|
||||
if Mem[CS:IP]<>ExpectSegOverride then
|
||||
Error;
|
||||
Inc(IP);
|
||||
end;
|
||||
if Mem[CS:IP]<>$FF then
|
||||
Error;
|
||||
Inc(IP);
|
||||
@ -115,6 +139,203 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure testlocallabels;
|
||||
label
|
||||
local_label2;
|
||||
begin
|
||||
ExpectSegOverride := SegOverrideCS;
|
||||
asm
|
||||
jmp @@skip_labels
|
||||
|
||||
@@local_label1:
|
||||
db 0, 0, 0, 0
|
||||
|
||||
local_label2:
|
||||
db 0, 0, 0, 0
|
||||
|
||||
@@skip_labels:
|
||||
int NearInt
|
||||
call word [@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr [@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr @@local_label1 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr [@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr @@local_label1 { far }
|
||||
|
||||
int NearInt
|
||||
call word [local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr [local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr local_label2 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr [local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr local_label2 { far }
|
||||
|
||||
{ explicit CS: prefix }
|
||||
int NearInt
|
||||
call word [cs:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr cs:[@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr [cs:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr cs:@@local_label1 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [cs:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr cs:[@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr [cs:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr cs:@@local_label1 { far }
|
||||
|
||||
int NearInt
|
||||
call word [cs:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr cs:[local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr [cs:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr cs:local_label2 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [cs:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr cs:[local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr [cs:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr cs:local_label2 { far }
|
||||
|
||||
{ explicit DS: prefix }
|
||||
mov byte ptr [ExpectSegOverride], NoSegOverride { no segment override
|
||||
should be produced, because DS is the default for the processor }
|
||||
int NearInt
|
||||
call word [ds:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr ds:[@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr [ds:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr ds:@@local_label1 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [ds:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr ds:[@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr [ds:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr ds:@@local_label1 { far }
|
||||
|
||||
int NearInt
|
||||
call word [ds:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr ds:[local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr [ds:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr ds:local_label2 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [ds:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr ds:[local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr [ds:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr ds:local_label2 { far }
|
||||
|
||||
{ explicit ES: prefix }
|
||||
mov byte ptr [ExpectSegOverride], SegOverrideES
|
||||
int NearInt
|
||||
call word [es:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr es:[@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr [es:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr es:@@local_label1 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [es:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr es:[@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr [es:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr es:@@local_label1 { far }
|
||||
|
||||
int NearInt
|
||||
call word [es:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr es:[local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr [es:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr es:local_label2 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [es:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr es:[local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr [es:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr es:local_label2 { far }
|
||||
|
||||
{ explicit SS: prefix }
|
||||
mov byte ptr [ExpectSegOverride], SegOverrideSS
|
||||
int NearInt
|
||||
call word [ss:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr ss:[@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr [ss:@@local_label1] { near }
|
||||
int NearInt
|
||||
call word ptr ss:@@local_label1 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [ss:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr ss:[@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr [ss:@@local_label1] { far }
|
||||
int FarInt
|
||||
call dword ptr ss:@@local_label1 { far }
|
||||
|
||||
int NearInt
|
||||
call word [ss:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr ss:[local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr [ss:local_label2] { near }
|
||||
int NearInt
|
||||
call word ptr ss:local_label2 { near }
|
||||
|
||||
int FarInt
|
||||
call dword [ss:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr ss:[local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr [ss:local_label2] { far }
|
||||
int FarInt
|
||||
call dword ptr ss:local_label2 { far }
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
g16: integer;
|
||||
g32: longint;
|
||||
@ -124,6 +345,7 @@ begin
|
||||
GetIntVec(FarInt, OldFarIntVec);
|
||||
SetIntVec(FarInt, Ptr(Seg(IntFarHandler),Ofs(IntFarHandler)));
|
||||
|
||||
ExpectSegOverride := 0;
|
||||
asm
|
||||
int NearInt
|
||||
call word ptr $1234
|
||||
@ -202,6 +424,7 @@ begin
|
||||
{$endif FPC}
|
||||
end;
|
||||
testloc(5, 10);
|
||||
testlocallabels;
|
||||
Writeln('Ok');
|
||||
|
||||
SetIntVec(NearInt, OldNearIntVec);
|
||||
|
Loading…
Reference in New Issue
Block a user