2
0
Эх сурвалжийг харах

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 -

nickysn 6 жил өмнө
parent
commit
cfa1ddb5e4

+ 2 - 1
compiler/x86/rax86int.pas

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

+ 223 - 0
tests/test/cpu16/i8086/tfarcal2.pp

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