* escape all occurrences of '$' in function-level inline assembly

o temporarily encode the uses of '$' for references to function-level inline
     assembly arguments as '^', because those have to remain/become a single
     '$'

git-svn-id: trunk@34898 -
This commit is contained in:
Jonas Maebe 2016-11-13 22:10:00 +00:00
parent 43e599d6be
commit e1e3ad15f0
2 changed files with 40 additions and 13 deletions

View File

@ -33,17 +33,15 @@ interface
type type
TLLVMInstrWriter = class; TLLVMInstrWriter = class;
TLLVMBaseInlineAssemblyDecorator = class TLLVMModuleInlineAssemblyDecorator = class(IExternalAssemblerOutputFileDecorator)
function LineFilter(const s: AnsiString): AnsiString; function LineFilter(const s: AnsiString): AnsiString;
end;
TLLVMModuleInlineAssemblyDecorator = class(TLLVMBaseInlineAssemblyDecorator,IExternalAssemblerOutputFileDecorator)
function LinePrefix: AnsiString; function LinePrefix: AnsiString;
function LinePostfix: AnsiString; function LinePostfix: AnsiString;
function LineEnding(const deflineending: ShortString): ShortString; function LineEnding(const deflineending: ShortString): ShortString;
end; end;
TLLVMFunctionInlineAssemblyDecorator = class(TLLVMBaseInlineAssemblyDecorator,IExternalAssemblerOutputFileDecorator) TLLVMFunctionInlineAssemblyDecorator = class(IExternalAssemblerOutputFileDecorator)
function LineFilter(const s: AnsiString): AnsiString;
function LinePrefix: AnsiString; function LinePrefix: AnsiString;
function LinePostfix: AnsiString; function LinePostfix: AnsiString;
function LineEnding(const deflineending: ShortString): ShortString; function LineEnding(const deflineending: ShortString): ShortString;
@ -151,10 +149,10 @@ implementation
end; end;
{****************************************************************************} {****************************************************************************}
{ Common decorator functionality for inline assembly } { Decorator for module-level inline assembly }
{****************************************************************************} {****************************************************************************}
function TLLVMBaseInlineAssemblyDecorator.LineFilter(const s: AnsiString): AnsiString; function TLLVMModuleInlineAssemblyDecorator.LineFilter(const s: AnsiString): AnsiString;
var var
i: longint; i: longint;
begin begin
@ -176,10 +174,6 @@ implementation
end; end;
{****************************************************************************}
{ Decorator for module-level inline assembly }
{****************************************************************************}
function TLLVMModuleInlineAssemblyDecorator.LinePrefix: AnsiString; function TLLVMModuleInlineAssemblyDecorator.LinePrefix: AnsiString;
begin begin
result:='module asm "'; result:='module asm "';
@ -203,6 +197,35 @@ implementation
{****************************************************************************} {****************************************************************************}
function TLLVMFunctionInlineAssemblyDecorator.LineFilter(const s: AnsiString): AnsiString;
var
i: longint;
begin
result:='';
for i:=1 to length(s) do
begin
case s[i] of
{ escape dollars }
'$':
result:=result+'$$';
{ ^ is used as placeholder for a single dollar (reference to
argument to the inline assembly) }
'^':
result:=result+'$';
#0..#31,
#127..#255,
'"','\':
result:=result+
'\'+
chr((ord(s[i]) shr 4)+ord('0'))+
chr((ord(s[i]) and $f)+ord('0'));
else
result:=result+s[i];
end;
end;
end;
function TLLVMFunctionInlineAssemblyDecorator.LinePrefix: AnsiString; function TLLVMFunctionInlineAssemblyDecorator.LinePrefix: AnsiString;
begin begin
result:=''; result:='';

View File

@ -109,7 +109,11 @@ interface
function tllvmasmnode.getllvmasmparasym(sym: tabstractnormalvarsym): tasmsymbol; function tllvmasmnode.getllvmasmparasym(sym: tabstractnormalvarsym): tasmsymbol;
begin begin
result:=current_asmdata.RefAsmSymbol('$'+tostr(getllvmasmopindexforsym(sym)),AT_DATA,false); { these have to be transformed from ^nr into into $nr; we use ^ because
we also have to double all other occurrences of '$' in the assembly
code, and we can't differentiate between these and other '$'s in
agllvm }
result:=current_asmdata.RefAsmSymbol('^'+tostr(getllvmasmopindexforsym(sym)),AT_DATA,false);
end; end;