+ 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:
nickysn 2018-02-26 17:17:47 +00:00
parent 34c0898d97
commit 45fdd7655d
6 changed files with 462 additions and 359 deletions

1
.gitattributes vendored
View File

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

View File

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

View File

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

View File

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