mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 07:09:09 +02:00
* throw an error if instructions which needs an operand size is used with one operand being a reference without size
This commit is contained in:
parent
5e9e30b5ac
commit
c718062d44
@ -659,6 +659,8 @@ interface
|
||||
function get_ref_address_size(const ref:treference):byte;
|
||||
function get_default_segment_of_ref(const ref:treference):tregister;
|
||||
procedure optimize_ref(var ref:treference; inlineasm: boolean);
|
||||
{ returns true if opcode can be used with one memory operand without size }
|
||||
function NoMemorySizeRequired(opcode : TAsmOp) : Boolean;
|
||||
|
||||
function spilling_create_load(const ref:treference;r:tregister):Taicpu;
|
||||
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
||||
@ -5581,6 +5583,32 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function NoMemorySizeRequired(opcode : TAsmOp) : Boolean;
|
||||
var
|
||||
i : LongInt;
|
||||
insentry : PInsEntry;
|
||||
begin
|
||||
result:=false;
|
||||
i:=instabcache^[opcode];
|
||||
if i=-1 then
|
||||
begin
|
||||
Message1(asmw_e_opcode_not_in_table,gas_op2str[opcode]);
|
||||
exit;
|
||||
end;
|
||||
insentry:=@instab[i];
|
||||
while (insentry^.opcode=opcode) do
|
||||
begin
|
||||
if (insentry^.ops=1) and (insentry^.optypes[0]=OT_MEMORY) then
|
||||
begin
|
||||
result:=true;
|
||||
exit;
|
||||
end;
|
||||
inc(insentry);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure InitAsm;
|
||||
begin
|
||||
build_spilling_operation_type_table;
|
||||
|
@ -436,10 +436,11 @@ begin
|
||||
Opsize:=S_NO;
|
||||
end;
|
||||
|
||||
procedure Tx86Instruction.AddReferenceSizes;
|
||||
{ this will add the sizes for references like [esi] which do not
|
||||
have the size set yet, it will take only the size if the other
|
||||
operand is a register }
|
||||
procedure Tx86Instruction.AddReferenceSizes;
|
||||
|
||||
var
|
||||
operand2,i,j,k : longint;
|
||||
s : tasmsymbol;
|
||||
@ -1400,6 +1401,16 @@ begin
|
||||
begin
|
||||
if opsize<>S_NO then
|
||||
tx86operand(operands[i]).opsize:=opsize
|
||||
else if not(NoMemorySizeRequired(opcode) or
|
||||
(opcode=A_JMP) or (opcode=A_JCC) or (opcode=A_CALL) or (opcode=A_LCALL) or (opcode=A_LJMP)) then
|
||||
begin
|
||||
if (m_delphi in current_settings.modeswitches) then
|
||||
Message(asmr_w_unable_to_determine_reference_size_using_dword)
|
||||
else
|
||||
Message(asmr_e_unable_to_determine_reference_size);
|
||||
{ recovery }
|
||||
tx86operand(operands[i]).opsize:=S_L;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
OPR_SYMBOL :
|
||||
|
10
tests/webtbf/tw40399.pp
Normal file
10
tests/webtbf/tw40399.pp
Normal file
@ -0,0 +1,10 @@
|
||||
{ %cpu=i386 }
|
||||
{ %fail }
|
||||
{$asmmode intel}
|
||||
|
||||
begin
|
||||
asm
|
||||
fnstcw [esi]
|
||||
imul [esi]
|
||||
end;
|
||||
end.
|
Loading…
Reference in New Issue
Block a user