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:
nickysn 2019-06-12 11:11:06 +00:00
parent 783273cf01
commit cfa1ddb5e4
2 changed files with 225 additions and 1 deletions

View File

@ -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

View File

@ -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);