* 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
TLLVMInstrWriter = class;
TLLVMBaseInlineAssemblyDecorator = class
function LineFilter(const s: AnsiString): AnsiString;
end;
TLLVMModuleInlineAssemblyDecorator = class(TLLVMBaseInlineAssemblyDecorator,IExternalAssemblerOutputFileDecorator)
TLLVMModuleInlineAssemblyDecorator = class(IExternalAssemblerOutputFileDecorator)
function LineFilter(const s: AnsiString): AnsiString;
function LinePrefix: AnsiString;
function LinePostfix: AnsiString;
function LineEnding(const deflineending: ShortString): ShortString;
end;
TLLVMFunctionInlineAssemblyDecorator = class(TLLVMBaseInlineAssemblyDecorator,IExternalAssemblerOutputFileDecorator)
TLLVMFunctionInlineAssemblyDecorator = class(IExternalAssemblerOutputFileDecorator)
function LineFilter(const s: AnsiString): AnsiString;
function LinePrefix: AnsiString;
function LinePostfix: AnsiString;
function LineEnding(const deflineending: ShortString): ShortString;
@ -151,10 +149,10 @@ implementation
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
i: longint;
begin
@ -176,10 +174,6 @@ implementation
end;
{****************************************************************************}
{ Decorator for module-level inline assembly }
{****************************************************************************}
function TLLVMModuleInlineAssemblyDecorator.LinePrefix: AnsiString;
begin
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;
begin
result:='';

View File

@ -109,7 +109,11 @@ interface
function tllvmasmnode.getllvmasmparasym(sym: tabstractnormalvarsym): tasmsymbol;
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;