mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 06:39:34 +02:00
+ allow segment override prefixes to be used as a standalone opcode in the intel
syntax inline assembler; this is TP7 compatible and allows compiling ugly code, such as 'seges; db $67,$66; lodsw' git-svn-id: trunk@38096 -
This commit is contained in:
parent
32fee98477
commit
1f0e311fdd
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -12488,6 +12488,7 @@ tests/test/tasm14e.pp svneol=native#text/plain
|
|||||||
tests/test/tasm14f.pp svneol=native#text/plain
|
tests/test/tasm14f.pp svneol=native#text/plain
|
||||||
tests/test/tasm15.pp svneol=native#text/plain
|
tests/test/tasm15.pp svneol=native#text/plain
|
||||||
tests/test/tasm15a.pp svneol=native#text/plain
|
tests/test/tasm15a.pp svneol=native#text/plain
|
||||||
|
tests/test/tasm16.pp svneol=native#text/plain
|
||||||
tests/test/tasm2.inc svneol=native#text/plain
|
tests/test/tasm2.inc svneol=native#text/plain
|
||||||
tests/test/tasm2.pp svneol=native#text/plain
|
tests/test/tasm2.pp svneol=native#text/plain
|
||||||
tests/test/tasm2a.pp svneol=native#text/plain
|
tests/test/tasm2a.pp svneol=native#text/plain
|
||||||
|
@ -1086,6 +1086,27 @@ interface
|
|||||||
internalerror(2017111001);
|
internalerror(2017111001);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
else if (fixed_opcode=A_SEGCS) or (fixed_opcode=A_SEGDS) or
|
||||||
|
(fixed_opcode=A_SEGSS) or (fixed_opcode=A_SEGES) or
|
||||||
|
(fixed_opcode=A_SEGFS) or (fixed_opcode=A_SEGGS) then
|
||||||
|
begin
|
||||||
|
case fixed_opcode of
|
||||||
|
A_SEGCS:
|
||||||
|
writer.AsmWrite(#9#9'cs');
|
||||||
|
A_SEGDS:
|
||||||
|
writer.AsmWrite(#9#9'ds');
|
||||||
|
A_SEGSS:
|
||||||
|
writer.AsmWrite(#9#9'ss');
|
||||||
|
A_SEGES:
|
||||||
|
writer.AsmWrite(#9#9'es');
|
||||||
|
A_SEGFS:
|
||||||
|
writer.AsmWrite(#9#9'fs');
|
||||||
|
A_SEGGS:
|
||||||
|
writer.AsmWrite(#9#9'gs');
|
||||||
|
else
|
||||||
|
internalerror(2018020101);
|
||||||
|
end;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
writer.AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
|
writer.AsmWrite(#9#9+prefix+std_op2str[fixed_opcode]+cond2str[taicpu(hp).condition]);
|
||||||
if taicpu(hp).ops<>0 then
|
if taicpu(hp).ops<>0 then
|
||||||
|
@ -2116,6 +2116,7 @@ Unit Rax86int;
|
|||||||
i:byte;
|
i:byte;
|
||||||
tmp: toperand;
|
tmp: toperand;
|
||||||
di_param, si_param: ShortInt;
|
di_param, si_param: ShortInt;
|
||||||
|
prefix_or_override_pending_concat: boolean = false;
|
||||||
{$ifdef i8086}
|
{$ifdef i8086}
|
||||||
hsymbol: TAsmSymbol;
|
hsymbol: TAsmSymbol;
|
||||||
hoffset: ASizeInt;
|
hoffset: ASizeInt;
|
||||||
@ -2130,22 +2131,26 @@ Unit Rax86int;
|
|||||||
if is_prefix(actopcode) then
|
if is_prefix(actopcode) then
|
||||||
with instr do
|
with instr do
|
||||||
begin
|
begin
|
||||||
|
if prefix_or_override_pending_concat then
|
||||||
|
ConcatInstruction(curlist);
|
||||||
PrefixOp:=ActOpcode;
|
PrefixOp:=ActOpcode;
|
||||||
opcode:=ActOpcode;
|
opcode:=ActOpcode;
|
||||||
condition:=ActCondition;
|
condition:=ActCondition;
|
||||||
opsize:=ActOpsize;
|
opsize:=ActOpsize;
|
||||||
ConcatInstruction(curlist);
|
prefix_or_override_pending_concat:=true;
|
||||||
consume(AS_OPCODE);
|
consume(AS_OPCODE);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if is_override(actopcode) then
|
if is_override(actopcode) then
|
||||||
with instr do
|
with instr do
|
||||||
begin
|
begin
|
||||||
|
if prefix_or_override_pending_concat then
|
||||||
|
ConcatInstruction(curlist);
|
||||||
OverrideOp:=ActOpcode;
|
OverrideOp:=ActOpcode;
|
||||||
opcode:=ActOpcode;
|
opcode:=ActOpcode;
|
||||||
condition:=ActCondition;
|
condition:=ActCondition;
|
||||||
opsize:=ActOpsize;
|
opsize:=ActOpsize;
|
||||||
ConcatInstruction(curlist);
|
prefix_or_override_pending_concat:=true;
|
||||||
consume(AS_OPCODE);
|
consume(AS_OPCODE);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -2157,10 +2162,23 @@ Unit Rax86int;
|
|||||||
{ opcode }
|
{ opcode }
|
||||||
if (actasmtoken <> AS_OPCODE) then
|
if (actasmtoken <> AS_OPCODE) then
|
||||||
begin
|
begin
|
||||||
Message(asmr_e_invalid_or_missing_opcode);
|
{ allow a prefix or override to be used standalone, like an opcode
|
||||||
RecoverConsume(false);
|
with zero operands; this is TP7 compatible and allows compiling
|
||||||
exit;
|
ugly code like 'seges; db $67,$66; lodsw' }
|
||||||
|
if prefix_or_override_pending_concat then
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_or_missing_opcode);
|
||||||
|
RecoverConsume(false);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
if prefix_or_override_pending_concat then
|
||||||
|
begin
|
||||||
|
instr.ConcatInstruction(curlist);
|
||||||
|
prefix_or_override_pending_concat:=false;
|
||||||
|
end;
|
||||||
{ Fill the instr object with the current state }
|
{ Fill the instr object with the current state }
|
||||||
with instr do
|
with instr do
|
||||||
begin
|
begin
|
||||||
|
250
tests/test/tasm16.pp
Normal file
250
tests/test/tasm16.pp
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
{ %CPU=i8086,i386,x86_64 }
|
||||||
|
|
||||||
|
program tasm16;
|
||||||
|
|
||||||
|
{$ifdef cpui8086}
|
||||||
|
{$asmcpu 80386}
|
||||||
|
{$endif cpui8086}
|
||||||
|
|
||||||
|
const
|
||||||
|
{$ifdef cpui8086}
|
||||||
|
expect1: array [0..3] of byte = (
|
||||||
|
$2E, // segcs
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$AD // lodsw
|
||||||
|
);
|
||||||
|
expect2: array [0..3] of byte = (
|
||||||
|
$3E, // segds
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$AD // lodsw
|
||||||
|
);
|
||||||
|
expect3: array [0..3] of byte = (
|
||||||
|
$36, // segss
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$AD // lodsw
|
||||||
|
);
|
||||||
|
expect4: array [0..3] of byte = (
|
||||||
|
$26, // seges
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$AD // lodsw
|
||||||
|
);
|
||||||
|
expect5: array [0..3] of byte = (
|
||||||
|
$64, // segfs
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$AD // lodsw
|
||||||
|
);
|
||||||
|
expect6: array [0..3] of byte = (
|
||||||
|
$65, // seggs
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$AD // lodsw
|
||||||
|
);
|
||||||
|
{$else}
|
||||||
|
expect1: array [0..4] of byte = (
|
||||||
|
$2E, // segcs
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$66,$AD // lodsw
|
||||||
|
);
|
||||||
|
expect2: array [0..4] of byte = (
|
||||||
|
$3E, // segds
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$66,$AD // lodsw
|
||||||
|
);
|
||||||
|
expect3: array [0..4] of byte = (
|
||||||
|
$36, // segss
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$66,$AD // lodsw
|
||||||
|
);
|
||||||
|
expect4: array [0..4] of byte = (
|
||||||
|
$26, // seges
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$66,$AD // lodsw
|
||||||
|
);
|
||||||
|
expect5: array [0..4] of byte = (
|
||||||
|
$64, // segfs
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$66,$AD // lodsw
|
||||||
|
);
|
||||||
|
expect6: array [0..4] of byte = (
|
||||||
|
$65, // seggs
|
||||||
|
$67,$66, // db $67,$66
|
||||||
|
$66,$AD // lodsw
|
||||||
|
);
|
||||||
|
{$endif}
|
||||||
|
expect7: array [0..0] of byte = (
|
||||||
|
$2E // segcs
|
||||||
|
);
|
||||||
|
expect8: array [0..0] of byte = (
|
||||||
|
$3E // segds
|
||||||
|
);
|
||||||
|
expect9: array [0..0] of byte = (
|
||||||
|
$36 // segss
|
||||||
|
);
|
||||||
|
expect10: array [0..0] of byte = (
|
||||||
|
$26 // seges
|
||||||
|
);
|
||||||
|
expect11: array [0..0] of byte = (
|
||||||
|
$64 // segfs
|
||||||
|
);
|
||||||
|
expect12: array [0..0] of byte = (
|
||||||
|
$65 // seggs
|
||||||
|
);
|
||||||
|
expect13: array [0..1] of byte = (
|
||||||
|
$2E,$AC // segcs lodsb
|
||||||
|
);
|
||||||
|
expect14: array [0..1] of byte = (
|
||||||
|
$3E,$AC // segds lodsb
|
||||||
|
);
|
||||||
|
expect15: array [0..1] of byte = (
|
||||||
|
$36,$AC // segss lodsb
|
||||||
|
);
|
||||||
|
expect16: array [0..1] of byte = (
|
||||||
|
$26,$AC // seges lodsb
|
||||||
|
);
|
||||||
|
expect17: array [0..1] of byte = (
|
||||||
|
$64,$AC // segfs lodsb
|
||||||
|
);
|
||||||
|
expect18: array [0..1] of byte = (
|
||||||
|
$65,$AC // seggs lodsb
|
||||||
|
);
|
||||||
|
|
||||||
|
{$asmmode intel}
|
||||||
|
|
||||||
|
procedure test1; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segcs; db $67,$66; lodsw
|
||||||
|
end;
|
||||||
|
procedure test2; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segds; db $67,$66; lodsw
|
||||||
|
end;
|
||||||
|
procedure test3; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segss; db $67,$66; lodsw
|
||||||
|
end;
|
||||||
|
procedure test4; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
seges; db $67,$66; lodsw
|
||||||
|
end;
|
||||||
|
procedure test5; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segfs; db $67,$66; lodsw
|
||||||
|
end;
|
||||||
|
procedure test6; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
seggs; db $67,$66; lodsw
|
||||||
|
end;
|
||||||
|
procedure test7; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segcs
|
||||||
|
end;
|
||||||
|
procedure test8; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segds
|
||||||
|
end;
|
||||||
|
procedure test9; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segss
|
||||||
|
end;
|
||||||
|
procedure test10; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
seges
|
||||||
|
end;
|
||||||
|
procedure test11; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segfs
|
||||||
|
end;
|
||||||
|
procedure test12; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
seggs
|
||||||
|
end;
|
||||||
|
procedure test13; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segcs lodsb
|
||||||
|
end;
|
||||||
|
procedure test14; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segds lodsb
|
||||||
|
end;
|
||||||
|
procedure test15; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segss lodsb
|
||||||
|
end;
|
||||||
|
procedure test16; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
seges lodsb
|
||||||
|
end;
|
||||||
|
procedure test17; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
segfs lodsb
|
||||||
|
end;
|
||||||
|
procedure test18; assembler; nostackframe;
|
||||||
|
asm
|
||||||
|
seggs lodsb
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Error;
|
||||||
|
begin
|
||||||
|
Writeln('Error!');
|
||||||
|
Halt(1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ifdef cpui8086}
|
||||||
|
{ This version works in all i8086 memory models }
|
||||||
|
function CompareCode(cp: CodePointer; dp: Pointer; sz: SizeInt): Boolean;
|
||||||
|
var
|
||||||
|
I: SizeInt;
|
||||||
|
begin
|
||||||
|
for I := 0 to sz - 1 do
|
||||||
|
if Mem[Seg(cp^):Ofs(cp^) + I] <> Mem[Seg(dp^):Ofs(dp^) + I] then
|
||||||
|
begin
|
||||||
|
CompareCode := False;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
CompareCode := True;
|
||||||
|
end;
|
||||||
|
{$else cpui8086}
|
||||||
|
function CompareCode(cp: CodePointer; dp: Pointer; sz: SizeInt): Boolean;
|
||||||
|
begin
|
||||||
|
CompareCode := CompareByte(cp^, dp^, sz) = 0;
|
||||||
|
end;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
|
begin
|
||||||
|
if not CompareCode(CodePointer(@test1), @expect1, SizeOf(expect1)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test2), @expect2, SizeOf(expect2)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test3), @expect3, SizeOf(expect3)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test4), @expect4, SizeOf(expect4)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test5), @expect5, SizeOf(expect5)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test6), @expect6, SizeOf(expect6)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test7), @expect7, SizeOf(expect7)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test8), @expect8, SizeOf(expect8)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test9), @expect9, SizeOf(expect9)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test10), @expect10, SizeOf(expect10)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test11), @expect11, SizeOf(expect11)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test12), @expect12, SizeOf(expect12)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test13), @expect13, SizeOf(expect13)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test14), @expect14, SizeOf(expect14)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test15), @expect15, SizeOf(expect15)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test16), @expect16, SizeOf(expect16)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test17), @expect17, SizeOf(expect17)) then
|
||||||
|
Error;
|
||||||
|
if not CompareCode(CodePointer(@test18), @expect18, SizeOf(expect18)) then
|
||||||
|
Error;
|
||||||
|
Writeln('Ok!')
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user