From cfa1ddb5e4051f64e816f9e5b4b9dc070e3c1fe3 Mon Sep 17 00:00:00 2001 From: nickysn Date: Wed, 12 Jun 2019 11:11:06 +0000 Subject: [PATCH] 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 - --- compiler/x86/rax86int.pas | 3 +- tests/test/cpu16/i8086/tfarcal2.pp | 223 +++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 1 deletion(-) diff --git a/compiler/x86/rax86int.pas b/compiler/x86/rax86int.pas index 0a61c69d47..dff476d1b3 100644 --- a/compiler/x86/rax86int.pas +++ b/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 diff --git a/tests/test/cpu16/i8086/tfarcal2.pp b/tests/test/cpu16/i8086/tfarcal2.pp index fbf45d2be1..28f6e20efe 100644 --- a/tests/test/cpu16/i8086/tfarcal2.pp +++ b/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);