mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-11 12:49:16 +02:00
+ support concatenation of references in x86 intel syntax inline asm:
[expr1][expr2] = [expr1+expr2] [expr1[expr2]] = [expr1+expr2] This is compatible with TP7's inline asm, and perhaps also with tasm/masm/delphi. git-svn-id: trunk@38352 -
This commit is contained in:
parent
34c0898d97
commit
45fdd7655d
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -12520,6 +12520,7 @@ tests/test/tasm21.pp svneol=native#text/plain
|
||||
tests/test/tasm21a.pp svneol=native#text/plain
|
||||
tests/test/tasm21b.pp svneol=native#text/plain
|
||||
tests/test/tasm22.pp svneol=native#text/plain
|
||||
tests/test/tasm23.pp svneol=native#text/plain
|
||||
tests/test/tasm2a.pp svneol=native#text/plain
|
||||
tests/test/tasm3.pp svneol=native#text/plain
|
||||
tests/test/tasm4.pp svneol=native#text/plain
|
||||
|
@ -2491,7 +2491,7 @@ cg_h_no_inline=06058_H_Call to subroutine "$1" marked as inline is not inlined
|
||||
#
|
||||
# Assembler reader
|
||||
#
|
||||
# 07137 is the last used one
|
||||
# 07139 is the last used one
|
||||
#
|
||||
asmr_d_start_reading=07000_DL_Starting $1 styled assembler parsing
|
||||
% This informs you that an assembler block is being parsed
|
||||
@ -2827,6 +2827,8 @@ asmr_w_pop_cs_not_portable=07136_W_Instruction "POP CS" is not portable (it only
|
||||
% The 'pop cs' instruction doesn't work on any CPU, except 8086 and 8088.
|
||||
asmr_e_public_must_be_used_before_label_definition=07137_E_Label $1 can only be declared public before it's defined
|
||||
asmr_e_local_label_cannot_be_declared_public=07138_E_Local label $1 cannot be declared public
|
||||
asmr_e_multiple_segment_overrides=07139_E_Cannot use multiple segment overrides
|
||||
asmr_w_multiple_segment_overrides=07140_W_Multiple segment overrides (only the last one will take effect)
|
||||
#
|
||||
# Assembler/binary writers
|
||||
#
|
||||
|
@ -824,6 +824,8 @@ const
|
||||
asmr_w_pop_cs_not_portable=07136;
|
||||
asmr_e_public_must_be_used_before_label_definition=07137;
|
||||
asmr_e_local_label_cannot_be_declared_public=07138;
|
||||
asmr_e_multiple_segment_overrides=07139;
|
||||
asmr_w_multiple_segment_overrides=07140;
|
||||
asmw_f_too_many_asm_files=08000;
|
||||
asmw_f_assembler_output_not_supported=08001;
|
||||
asmw_f_comp_not_supported=08002;
|
||||
@ -1096,9 +1098,9 @@ const
|
||||
option_info=11024;
|
||||
option_help_pages=11025;
|
||||
|
||||
MsgTxtSize = 81436;
|
||||
MsgTxtSize = 81554;
|
||||
|
||||
MsgIdxMax : array[1..20] of longint=(
|
||||
27,106,347,126,96,59,139,34,221,67,
|
||||
27,106,347,126,96,59,141,34,221,67,
|
||||
61,20,30,1,1,1,1,1,1,1
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -63,6 +63,7 @@ Unit Rax86int;
|
||||
procedure GetToken;
|
||||
function consume(t : tasmtoken):boolean;
|
||||
procedure RecoverConsume(allowcomma:boolean);
|
||||
procedure AddReferences(dest,src : tx86operand);
|
||||
procedure BuildRecordOffsetSize(const expr: string;out offset:tcgint;out size:tcgint; out mangledname: string; needvmtofs: boolean; out hastypecast: boolean);
|
||||
procedure BuildConstSymbolExpression(needofs,isref,startingminus:boolean;out value:tcgint;out asmsym:string;out asmsymtyp:TAsmsymtype;out size:tcgint;out isseg,is_farproc_entry,hasofs:boolean);
|
||||
function BuildConstExpression:aint;
|
||||
@ -798,6 +799,69 @@ Unit Rax86int;
|
||||
Parsing Helpers
|
||||
*****************************************************************************}
|
||||
|
||||
{ Adds two references (dest:=dest+src) }
|
||||
procedure tx86intreader.AddReferences(dest,src : tx86operand);
|
||||
|
||||
procedure AddRegister(reg:tregister;scalefactor:byte);
|
||||
begin
|
||||
if reg=NR_NO then
|
||||
exit;
|
||||
if (dest.opr.ref.base=NR_NO) and (scalefactor=1) then
|
||||
begin
|
||||
dest.opr.ref.base:=reg;
|
||||
exit;
|
||||
end;
|
||||
if dest.opr.ref.index=NR_NO then
|
||||
begin
|
||||
dest.opr.ref.index:=reg;
|
||||
exit;
|
||||
end;
|
||||
if dest.opr.ref.index=reg then
|
||||
begin
|
||||
Inc(dest.opr.ref.scalefactor,scalefactor);
|
||||
exit;
|
||||
end;
|
||||
Message(asmr_e_multiple_index);
|
||||
end;
|
||||
|
||||
begin
|
||||
if (dest.opr.typ<>OPR_REFERENCE) or (src.opr.typ<>OPR_REFERENCE) then
|
||||
internalerror(2018022601);
|
||||
AddRegister(src.opr.ref.base,1);
|
||||
AddRegister(src.opr.ref.index,src.opr.ref.scalefactor);
|
||||
if src.opr.ref.segment<>NR_NO then
|
||||
begin
|
||||
if dest.opr.ref.segment<>NR_NO then
|
||||
begin
|
||||
if m_tp7 in current_settings.modeswitches then
|
||||
Message(asmr_w_multiple_segment_overrides)
|
||||
else
|
||||
Message(asmr_e_multiple_segment_overrides);
|
||||
end;
|
||||
dest.opr.ref.segment:=src.opr.ref.segment;
|
||||
end;
|
||||
Inc(dest.opr.ref.offset,src.opr.ref.offset);
|
||||
Inc(dest.opr.constoffset,src.opr.constoffset);
|
||||
dest.haslabelref:=dest.haslabelref or src.haslabelref;
|
||||
dest.hasproc:=dest.hasproc or src.hasproc;
|
||||
dest.hasvar:=dest.hasvar or src.hasvar;
|
||||
if assigned(src.opr.ref.symbol) then
|
||||
begin
|
||||
if assigned(dest.opr.ref.symbol) then
|
||||
Message(asmr_e_cant_have_multiple_relocatable_symbols);
|
||||
dest.opr.ref.symbol:=src.opr.ref.symbol;
|
||||
end;
|
||||
if assigned(src.opr.ref.relsymbol) then
|
||||
begin
|
||||
if assigned(dest.opr.ref.relsymbol) then
|
||||
Message(asmr_e_cant_have_multiple_relocatable_symbols);
|
||||
dest.opr.ref.relsymbol:=src.opr.ref.relsymbol;
|
||||
end;
|
||||
if dest.opr.ref.refaddr=addr_no then
|
||||
dest.opr.ref.refaddr:=src.opr.ref.refaddr;
|
||||
end;
|
||||
|
||||
|
||||
{ This routine builds up a record offset after a AS_DOT
|
||||
token is encountered.
|
||||
On entry actasmtoken should be equal to AS_DOT }
|
||||
@ -1282,6 +1346,7 @@ Unit Rax86int;
|
||||
isseg: boolean;
|
||||
is_farproc_entry,hasofs,
|
||||
hastypecast: boolean;
|
||||
tmpoper: tx86operand;
|
||||
Begin
|
||||
if actasmtoken=AS_LBRACKET then
|
||||
begin
|
||||
@ -1677,11 +1742,26 @@ Unit Rax86int;
|
||||
GotStar:=(prevasmtoken=AS_STAR);
|
||||
end;
|
||||
|
||||
AS_LBRACKET :
|
||||
begin
|
||||
tmpoper:=Tx86Operand.create;
|
||||
BuildReference(tmpoper);
|
||||
AddReferences(oper,tmpoper);
|
||||
tmpoper.Free;
|
||||
end;
|
||||
|
||||
AS_RBRACKET :
|
||||
begin
|
||||
if GotPlus or GotStar or BracketlessReference then
|
||||
Message(asmr_e_invalid_reference_syntax);
|
||||
Consume(AS_RBRACKET);
|
||||
if actasmtoken=AS_LBRACKET then
|
||||
begin
|
||||
tmpoper:=Tx86Operand.create;
|
||||
BuildReference(tmpoper);
|
||||
AddReferences(oper,tmpoper);
|
||||
tmpoper.Free;
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
|
||||
|
11
tests/test/tasm23.pp
Normal file
11
tests/test/tasm23.pp
Normal file
@ -0,0 +1,11 @@
|
||||
{ %CPU=i8086 }
|
||||
|
||||
program tasm23;
|
||||
|
||||
procedure t; assembler;
|
||||
asm
|
||||
mov ax, [bx[5]][di][54][-17][45][4] { mov ax, ss:[bx+di+5Bh] }
|
||||
end;
|
||||
|
||||
begin
|
||||
end.
|
Loading…
Reference in New Issue
Block a user