mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 16:09:23 +02:00
* migrated the handling of ansi/unicodestring constants to the high level
typed constant builder + llvm implementation git-svn-id: branches/hlcgllvm@28327 -
This commit is contained in:
parent
099588aaf5
commit
9e074d036b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -106,7 +106,6 @@ compiler/arm/rarmstd.inc svneol=native#text/plain
|
|||||||
compiler/arm/rarmsup.inc svneol=native#text/plain
|
compiler/arm/rarmsup.inc svneol=native#text/plain
|
||||||
compiler/arm/rgcpu.pas svneol=native#text/plain
|
compiler/arm/rgcpu.pas svneol=native#text/plain
|
||||||
compiler/arm/symcpu.pas svneol=native#text/plain
|
compiler/arm/symcpu.pas svneol=native#text/plain
|
||||||
compiler/asmutils.pas svneol=native#text/plain
|
|
||||||
compiler/assemble.pas svneol=native#text/plain
|
compiler/assemble.pas svneol=native#text/plain
|
||||||
compiler/avr/aasmcpu.pas svneol=native#text/plain
|
compiler/avr/aasmcpu.pas svneol=native#text/plain
|
||||||
compiler/avr/agavrgas.pas svneol=native#text/plain
|
compiler/avr/agavrgas.pas svneol=native#text/plain
|
||||||
|
@ -95,6 +95,11 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
tasmlabofs = record
|
||||||
|
lab: tasmlabel;
|
||||||
|
ofs: asizeint;
|
||||||
|
end;
|
||||||
|
|
||||||
{ Warning: never directly create a ttai_typedconstbuilder instance,
|
{ Warning: never directly create a ttai_typedconstbuilder instance,
|
||||||
instead create a cai_typedconstbuilder (this class can be overridden) }
|
instead create a cai_typedconstbuilder (this class can be overridden) }
|
||||||
ttai_lowleveltypedconstbuilder = class abstract
|
ttai_lowleveltypedconstbuilder = class abstract
|
||||||
@ -124,6 +129,17 @@ type
|
|||||||
want to use it explicitly as a procdef (i.e., not as a record with a
|
want to use it explicitly as a procdef (i.e., not as a record with a
|
||||||
code and data pointer in case of a complex procvardef) }
|
code and data pointer in case of a complex procvardef) }
|
||||||
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
|
procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
|
||||||
|
|
||||||
|
protected
|
||||||
|
function emit_string_const_common(list: TAsmList; stringtype: tstringtype; len: asizeint; encoding: tstringencoding; out startlab: tasmlabel):tasmlabofs;
|
||||||
|
public
|
||||||
|
class function get_dynstring_rec_name(typ: tstringtype; winlike: boolean; len: asizeint): string;
|
||||||
|
{ class functions and an extra list parameter, because emitting the data
|
||||||
|
for the strings has to happen via a separate typed const builder (which
|
||||||
|
will be created/destroyed internally by these methods) }
|
||||||
|
class function emit_ansistring_const(list: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding; newsection: boolean): tasmlabofs;
|
||||||
|
class function emit_unicodestring_const(list: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):tasmlabofs;
|
||||||
|
|
||||||
{ begin a potential aggregate type. Must be called for any type
|
{ begin a potential aggregate type. Must be called for any type
|
||||||
that consists of multiple tai constant data entries, or that
|
that consists of multiple tai constant data entries, or that
|
||||||
represents an aggregate at the Pascal level (a record, a non-dynamic
|
represents an aggregate at the Pascal level (a record, a non-dynamic
|
||||||
@ -515,6 +531,151 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ttai_lowleveltypedconstbuilder.emit_string_const_common(list: TAsmList; stringtype: tstringtype; len: asizeint; encoding: tstringencoding; out startlab: tasmlabel): tasmlabofs;
|
||||||
|
var
|
||||||
|
string_symofs: asizeint;
|
||||||
|
elesize: word;
|
||||||
|
begin
|
||||||
|
current_asmdata.getdatalabel(result.lab);
|
||||||
|
startlab:=result.lab;
|
||||||
|
result.ofs:=0;
|
||||||
|
begin_anonymous_record;
|
||||||
|
string_symofs:=get_string_symofs(stringtype,false);
|
||||||
|
{ encoding }
|
||||||
|
emit_tai(tai_const.create_16bit(encoding),u16inttype);
|
||||||
|
inc(result.ofs,2);
|
||||||
|
{ element size }
|
||||||
|
case stringtype of
|
||||||
|
st_ansistring:
|
||||||
|
elesize:=1;
|
||||||
|
st_unicodestring:
|
||||||
|
elesize:=2;
|
||||||
|
else
|
||||||
|
internalerror(2014080401);
|
||||||
|
end;
|
||||||
|
emit_tai(tai_const.create_16bit(elesize),u16inttype);
|
||||||
|
inc(result.ofs,2);
|
||||||
|
{$ifdef cpu64bitaddr}
|
||||||
|
{ dummy for alignment }
|
||||||
|
emit_tai(tai_const.create_32bit(0),u32inttype);
|
||||||
|
inc(result.ofs,4);
|
||||||
|
{$endif cpu64bitaddr}
|
||||||
|
emit_tai(tai_const.create_pint(-1),ptrsinttype);
|
||||||
|
inc(result.ofs,sizeof(pint));
|
||||||
|
emit_tai(tai_const.create_pint(len),ptrsinttype);
|
||||||
|
inc(result.ofs,sizeof(pint));
|
||||||
|
if string_symofs=0 then
|
||||||
|
begin
|
||||||
|
{ results in slightly more efficient code }
|
||||||
|
list.concat(tai_label.create(result.lab));
|
||||||
|
result.ofs:=0;
|
||||||
|
current_asmdata.getdatalabel(startlab);
|
||||||
|
end;
|
||||||
|
{ sanity check }
|
||||||
|
if result.ofs<>string_symofs then
|
||||||
|
internalerror(2012051701);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class function ttai_lowleveltypedconstbuilder.get_dynstring_rec_name(typ: tstringtype; winlike: boolean; len: asizeint): string;
|
||||||
|
begin
|
||||||
|
case typ of
|
||||||
|
st_ansistring:
|
||||||
|
result:='ansistrrec';
|
||||||
|
st_unicodestring,
|
||||||
|
st_widestring:
|
||||||
|
if (typ=st_unicodestring) or
|
||||||
|
not winlike then
|
||||||
|
result:='unicodestrrec'
|
||||||
|
else
|
||||||
|
result:='widestrrec';
|
||||||
|
else
|
||||||
|
internalerror(2014080402);
|
||||||
|
end;
|
||||||
|
result:=result+tostr(len);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class function ttai_lowleveltypedconstbuilder.emit_ansistring_const(list: TAsmList; data: pchar; len: asizeint; encoding: tstringencoding; newsection: boolean): tasmlabofs;
|
||||||
|
var
|
||||||
|
s: PChar;
|
||||||
|
startlab: tasmlabel;
|
||||||
|
sectype: TAsmSectiontype;
|
||||||
|
ansistrrecdef: trecorddef;
|
||||||
|
datadef: tdef;
|
||||||
|
datatcb: ttai_lowleveltypedconstbuilder;
|
||||||
|
begin
|
||||||
|
datatcb:=self.create;
|
||||||
|
result:=datatcb.emit_string_const_common(list,st_ansistring,len,encoding,startlab);
|
||||||
|
|
||||||
|
getmem(s,len+1);
|
||||||
|
move(data^,s^,len);
|
||||||
|
s[len]:=#0;
|
||||||
|
{ terminating zero included }
|
||||||
|
datadef:=getarraydef(cansichartype,len+1);
|
||||||
|
datatcb.maybe_begin_aggregate(datadef);
|
||||||
|
datatcb.emit_tai(tai_string.create_pchar(s,len+1),datadef);
|
||||||
|
datatcb.maybe_end_aggregate(datadef);
|
||||||
|
ansistrrecdef:=datatcb.end_anonymous_record('$'+get_dynstring_rec_name(st_ansistring,false,len),sizeof(pint));
|
||||||
|
if NewSection then
|
||||||
|
sectype:=sec_rodata_norel
|
||||||
|
else
|
||||||
|
sectype:=sec_none;
|
||||||
|
list.concatlist(datatcb.get_final_asmlist(startlab,ansistrrecdef,sectype,startlab.name,const_align(sizeof(pint)),true));
|
||||||
|
datatcb.free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class function ttai_lowleveltypedconstbuilder.emit_unicodestring_const(list: TAsmList; data: pointer; encoding: tstringencoding; winlike: boolean):tasmlabofs;
|
||||||
|
var
|
||||||
|
i, strlength: longint;
|
||||||
|
string_symofs: asizeint;
|
||||||
|
startlab: tasmlabel;
|
||||||
|
datadef: tdef;
|
||||||
|
uniwidestrrecdef: trecorddef;
|
||||||
|
datatcb: ttai_lowleveltypedconstbuilder;
|
||||||
|
begin
|
||||||
|
datatcb:=self.create;
|
||||||
|
strlength:=getlengthwidestring(pcompilerwidestring(data));
|
||||||
|
if winlike then
|
||||||
|
begin
|
||||||
|
current_asmdata.getdatalabel(result.lab);
|
||||||
|
datatcb.emit_tai(Tai_const.Create_32bit(strlength*cwidechartype.size),s32inttype);
|
||||||
|
{ can we optimise by placing the string constant label at the
|
||||||
|
required offset? }
|
||||||
|
string_symofs:=get_string_symofs(st_widestring,true);
|
||||||
|
if string_symofs=0 then
|
||||||
|
begin
|
||||||
|
{ yes }
|
||||||
|
datatcb.emit_tai(Tai_label.Create(result.lab),widecharpointertype);
|
||||||
|
{ allocate a separate label for the start of the data }
|
||||||
|
current_asmdata.getdatalabel(startlab);
|
||||||
|
end;
|
||||||
|
result.ofs:=string_symofs;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
result:=datatcb.emit_string_const_common(list,st_unicodestring,strlength,encoding,startlab);
|
||||||
|
end;
|
||||||
|
if cwidechartype.size = 2 then
|
||||||
|
begin
|
||||||
|
datadef:=getarraydef(cwidechartype,strlength+1);
|
||||||
|
datatcb.maybe_begin_aggregate(datadef);
|
||||||
|
for i:=0 to strlength-1 do
|
||||||
|
datatcb.emit_tai(Tai_const.Create_16bit(pcompilerwidestring(data)^.data[i]),cwidechartype);
|
||||||
|
{ ending #0 }
|
||||||
|
datatcb.emit_tai(Tai_const.Create_16bit(0),cwidechartype);
|
||||||
|
datatcb.maybe_end_aggregate(datadef);
|
||||||
|
uniwidestrrecdef:=datatcb.end_anonymous_record('$'+get_dynstring_rec_name(st_widestring,winlike,strlength),sizeof(pint));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ code generation for other sizes must be written }
|
||||||
|
internalerror(200904271);
|
||||||
|
list.concatlist(datatcb.get_final_asmlist(startlab,uniwidestrrecdef,sec_rodata_norel,startlab.name,const_align(sizeof(pint)),true));
|
||||||
|
datatcb.free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure ttai_lowleveltypedconstbuilder.maybe_begin_aggregate(def: tdef);
|
procedure ttai_lowleveltypedconstbuilder.maybe_begin_aggregate(def: tdef);
|
||||||
begin
|
begin
|
||||||
{ do nothing }
|
{ do nothing }
|
||||||
|
@ -1,157 +0,0 @@
|
|||||||
{
|
|
||||||
Copyright (c) 1998-2006 by Florian Klaempfl
|
|
||||||
|
|
||||||
This unit contains utility functions for assembler output
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
****************************************************************************
|
|
||||||
}
|
|
||||||
unit asmutils;
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
{$i fpcdefs.inc}
|
|
||||||
|
|
||||||
uses
|
|
||||||
globtype,
|
|
||||||
aasmbase,
|
|
||||||
aasmdata,
|
|
||||||
symconst;
|
|
||||||
|
|
||||||
type
|
|
||||||
tasmlabofs = record
|
|
||||||
lab: tasmlabel;
|
|
||||||
ofs: pint;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;encoding:tstringencoding;NewSection:Boolean=True):tasmlabofs;
|
|
||||||
function emit_unicodestring_const(list:TAsmList;data:Pointer;encoding:tstringencoding;Winlike:Boolean):tasmlabofs;
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
uses
|
|
||||||
globals,
|
|
||||||
systems,
|
|
||||||
verbose,
|
|
||||||
aasmtai,aasmcnst,
|
|
||||||
widestr,
|
|
||||||
symdef;
|
|
||||||
|
|
||||||
function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;encoding:tstringencoding;NewSection:Boolean): tasmlabofs;
|
|
||||||
var
|
|
||||||
s: PChar;
|
|
||||||
begin
|
|
||||||
current_asmdata.getdatalabel(result.lab);
|
|
||||||
result.ofs:=0;
|
|
||||||
if NewSection then
|
|
||||||
begin
|
|
||||||
maybe_new_object_file(list);
|
|
||||||
new_section(list,sec_rodata_norel,result.lab.name,const_align(sizeof(pint)));
|
|
||||||
end;
|
|
||||||
{ put label before header on Darwin, because there the linker considers
|
|
||||||
a global symbol to be the start of a new subsection }
|
|
||||||
if target_info.system in systems_darwin then
|
|
||||||
list.concat(tai_label.create(result.lab));
|
|
||||||
list.concat(tai_const.create_16bit(encoding));
|
|
||||||
inc(result.ofs,2);
|
|
||||||
list.concat(tai_const.create_16bit(1));
|
|
||||||
inc(result.ofs,2);
|
|
||||||
{$ifdef cpu64bitaddr}
|
|
||||||
{ dummy for alignment }
|
|
||||||
list.concat(tai_const.create_32bit(0));
|
|
||||||
inc(result.ofs,4);
|
|
||||||
{$endif cpu64bitaddr}
|
|
||||||
list.concat(tai_const.create_pint(-1));
|
|
||||||
inc(result.ofs,sizeof(pint));
|
|
||||||
list.concat(tai_const.create_pint(len));
|
|
||||||
inc(result.ofs,sizeof(pint));
|
|
||||||
if not(target_info.system in systems_darwin) then
|
|
||||||
begin
|
|
||||||
{ results in slightly more efficient code }
|
|
||||||
list.concat(tai_label.create(result.lab));
|
|
||||||
result.ofs:=0;
|
|
||||||
end;
|
|
||||||
{ sanity check }
|
|
||||||
if result.ofs<>ctai_typedconstbuilder.get_string_symofs(st_ansistring,false) then
|
|
||||||
internalerror(2012051701);
|
|
||||||
|
|
||||||
getmem(s,len+1);
|
|
||||||
move(data^,s^,len);
|
|
||||||
s[len]:=#0;
|
|
||||||
list.concat(tai_string.create_pchar(s,len+1)); { terminating zero included }
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function emit_unicodestring_const(list:TAsmList;data:Pointer;encoding:tstringencoding;Winlike:Boolean):tasmlabofs;
|
|
||||||
var
|
|
||||||
i, strlength: SizeInt;
|
|
||||||
begin
|
|
||||||
current_asmdata.getdatalabel(result.lab);
|
|
||||||
result.ofs:=0;
|
|
||||||
maybe_new_object_file(list);
|
|
||||||
new_section(list,sec_rodata_norel,result.lab.name,const_align(sizeof(pint)));
|
|
||||||
strlength := getlengthwidestring(pcompilerwidestring(data));
|
|
||||||
if Winlike then
|
|
||||||
begin
|
|
||||||
list.concat(Tai_const.Create_32bit(strlength*cwidechartype.size));
|
|
||||||
{ don't increase result.ofs, this is how Windows widestrings are
|
|
||||||
defined by the OS: a pointer 4 bytes past the length of the
|
|
||||||
string }
|
|
||||||
list.concat(Tai_label.Create(result.lab));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
{ put label before header on Darwin, because there the linker considers
|
|
||||||
a global symbol to be the start of a new subsection }
|
|
||||||
if target_info.system in systems_darwin then
|
|
||||||
list.concat(Tai_label.Create(result.lab));
|
|
||||||
list.concat(tai_const.create_16bit(encoding));
|
|
||||||
inc(result.ofs,2);
|
|
||||||
list.concat(tai_const.create_16bit(2));
|
|
||||||
inc(result.ofs,2);
|
|
||||||
{$ifdef cpu64bitaddr}
|
|
||||||
{ dummy for alignment }
|
|
||||||
list.concat(Tai_const.Create_32bit(0));
|
|
||||||
inc(result.ofs,4);
|
|
||||||
{$endif cpu64bitaddr}
|
|
||||||
list.concat(Tai_const.Create_pint(-1));
|
|
||||||
inc(result.ofs,sizeof(pint));
|
|
||||||
list.concat(Tai_const.Create_pint(strlength));
|
|
||||||
inc(result.ofs,sizeof(pint));
|
|
||||||
if not(target_info.system in systems_darwin) then
|
|
||||||
begin
|
|
||||||
{ results in slightly more efficient code }
|
|
||||||
list.concat(tai_label.create(result.lab));
|
|
||||||
result.ofs:=0;
|
|
||||||
end;
|
|
||||||
{ sanity check }
|
|
||||||
if result.ofs<>ctai_typedconstbuilder.get_string_symofs(st_unicodestring,false) then
|
|
||||||
internalerror(2012051702);
|
|
||||||
end;
|
|
||||||
if cwidechartype.size = 2 then
|
|
||||||
begin
|
|
||||||
for i:=0 to strlength-1 do
|
|
||||||
list.concat(Tai_const.Create_16bit(pcompilerwidestring(data)^.data[i]));
|
|
||||||
{ ending #0 }
|
|
||||||
list.concat(Tai_const.Create_16bit(0));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
InternalError(200904271); { codegeneration for other sizes must be written }
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
end.
|
|
@ -32,16 +32,15 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils,
|
SysUtils,
|
||||||
|
{$if FPC_FULLVERSION<20700}
|
||||||
|
ccharset,
|
||||||
|
{$endif}
|
||||||
cclasses,widestr,
|
cclasses,widestr,
|
||||||
cutils,globtype,globals,systems,
|
cutils,globtype,globals,systems,
|
||||||
symconst,symtype,symdef,symsym,
|
symconst,symtype,symdef,symsym,
|
||||||
verbose,fmodule,ppu,
|
verbose,fmodule,ppu,
|
||||||
aasmbase,aasmtai,aasmdata,
|
aasmbase,aasmtai,aasmdata,aasmcnst,
|
||||||
aasmcpu,
|
aasmcpu;
|
||||||
{$if FPC_FULLVERSION<20700}
|
|
||||||
ccharset,
|
|
||||||
{$endif}
|
|
||||||
asmutils;
|
|
||||||
|
|
||||||
Type
|
Type
|
||||||
{ These are used to form a singly-linked list, ordered by hash value }
|
{ These are used to form a singly-linked list, ordered by hash value }
|
||||||
@ -150,7 +149,7 @@ uses
|
|||||||
make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
|
make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
|
||||||
|
|
||||||
{ Write unitname entry }
|
{ Write unitname entry }
|
||||||
namelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),getansistringcodepage,False);
|
namelab:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),getansistringcodepage,False);
|
||||||
current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(namelab.lab,namelab.ofs));
|
current_asmdata.asmlists[al_resourcestrings].concat(tai_const.Create_sym_offset(namelab.lab,namelab.ofs));
|
||||||
current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
|
current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
|
||||||
current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
|
current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_nil_dataptr);
|
||||||
@ -166,7 +165,7 @@ uses
|
|||||||
new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
|
new_section(current_asmdata.asmlists[al_const],sec_rodata_norel,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
|
||||||
{ Write default value }
|
{ Write default value }
|
||||||
if assigned(R.value) and (R.len<>0) then
|
if assigned(R.value) and (R.len<>0) then
|
||||||
valuelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage,False)
|
valuelab:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,getansistringcodepage,False)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
valuelab.lab:=nil;
|
valuelab.lab:=nil;
|
||||||
@ -174,7 +173,7 @@ uses
|
|||||||
end;
|
end;
|
||||||
{ Append the name as a ansistring. }
|
{ Append the name as a ansistring. }
|
||||||
current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
|
current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
|
||||||
namelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),getansistringcodepage,False);
|
namelab:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),getansistringcodepage,False);
|
||||||
|
|
||||||
{
|
{
|
||||||
Resourcestring index:
|
Resourcestring index:
|
||||||
|
@ -27,7 +27,8 @@ unit nllvmcon;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
node,ncgcon;
|
symtype,
|
||||||
|
node,ncgcon;
|
||||||
|
|
||||||
type
|
type
|
||||||
tllvmrealconstnode = class(tcgrealconstnode)
|
tllvmrealconstnode = class(tcgrealconstnode)
|
||||||
@ -37,14 +38,16 @@ interface
|
|||||||
|
|
||||||
tllvmstringconstnode = class(tcgstringconstnode)
|
tllvmstringconstnode = class(tcgstringconstnode)
|
||||||
procedure pass_generate_code; override;
|
procedure pass_generate_code; override;
|
||||||
|
protected
|
||||||
|
procedure load_dynstring(const strpointerdef: tdef; const elementdef: tdef; const winlikewidestring: boolean); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
globtype,verbose,cutils,
|
globtype,globals,verbose,cutils,
|
||||||
symtype,symdef,defutil,
|
symbase,symtable,symconst,symdef,symsym,defutil,
|
||||||
aasmdata,
|
aasmdata,aasmcnst,
|
||||||
ncon,
|
ncon,
|
||||||
llvmbase,aasmllvm,hlcgobj,
|
llvmbase,aasmllvm,hlcgobj,
|
||||||
cgbase,cgutils;
|
cgbase,cgutils;
|
||||||
@ -87,6 +90,49 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tllvmstringconstnode.load_dynstring(const strpointerdef: tdef; const elementdef: tdef; const winlikewidestring: boolean);
|
||||||
|
var
|
||||||
|
stringtype: tstringtype;
|
||||||
|
strrecdef: trecorddef;
|
||||||
|
srsym: tsym;
|
||||||
|
srsymtable: tsymtable;
|
||||||
|
offset: pint;
|
||||||
|
field: tfieldvarsym;
|
||||||
|
dataptrdef: tdef;
|
||||||
|
reg: tregister;
|
||||||
|
href: treference;
|
||||||
|
begin
|
||||||
|
case cst_type of
|
||||||
|
cst_ansistring:
|
||||||
|
stringtype:=st_ansistring;
|
||||||
|
cst_unicodestring:
|
||||||
|
stringtype:=st_unicodestring;
|
||||||
|
cst_widestring:
|
||||||
|
stringtype:=st_widestring;
|
||||||
|
else
|
||||||
|
internalerror(2014040804);
|
||||||
|
end;
|
||||||
|
{ get the recorddef for this string constant }
|
||||||
|
if not searchsym_type(ctai_typedconstbuilder.get_dynstring_rec_name(stringtype,winlikewidestring,len),srsym,srsymtable) then
|
||||||
|
internalerror(2014080405);
|
||||||
|
strrecdef:=trecorddef(ttypesym(srsym).typedef);
|
||||||
|
{ offset in the record of the the string data }
|
||||||
|
offset:=ctai_typedconstbuilder.get_string_symofs(stringtype,winlikewidestring);
|
||||||
|
{ field corresponding to this offset }
|
||||||
|
field:=trecordsymtable(strrecdef.symtable).findfieldbyoffset(offset);
|
||||||
|
{ pointerdef to the string data array }
|
||||||
|
dataptrdef:=getpointerdef(field.vardef);
|
||||||
|
{ load the address of the string data }
|
||||||
|
reg:=hlcg.getaddressregister(current_asmdata.CurrAsmList,dataptrdef);
|
||||||
|
reference_reset_symbol(href, lab_str, 0, const_align(strpointerdef.size));
|
||||||
|
current_asmdata.CurrAsmList.concat(
|
||||||
|
taillvm.getelementptr_reg_size_ref_size_const(reg,dataptrdef,href,
|
||||||
|
s32inttype,field.llvmfieldnr,true));
|
||||||
|
{ convert into a pointer to the individual elements }
|
||||||
|
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,dataptrdef,strpointerdef,reg,location.register);
|
||||||
|
end;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
tllvmrealconstnode
|
tllvmrealconstnode
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
@ -73,6 +73,12 @@ interface
|
|||||||
class function get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; override;
|
class function get_string_symofs(typ: tstringtype; winlikewidestring: boolean): pint; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
tllvmasmlisttypedconstbuilder = class(tasmlisttypedconstbuilder)
|
||||||
|
protected
|
||||||
|
procedure tc_emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef); override;
|
||||||
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -435,7 +441,46 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ tllvmasmlisttypedconstbuilder }
|
||||||
|
|
||||||
|
procedure tllvmasmlisttypedconstbuilder.tc_emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);
|
||||||
|
var
|
||||||
|
srsym : tsym;
|
||||||
|
srsymtable: tsymtable;
|
||||||
|
strrecdef : trecorddef;
|
||||||
|
offset: pint;
|
||||||
|
field: tfieldvarsym;
|
||||||
|
dataptrdef: tdef;
|
||||||
|
begin
|
||||||
|
{ if the returned offset is <> 0, then the string data
|
||||||
|
starts at that offset -> translate to a field for the
|
||||||
|
high level code generator }
|
||||||
|
if ll.ofs<>0 then
|
||||||
|
begin
|
||||||
|
{ get the recorddef for this string constant }
|
||||||
|
if not searchsym_type(ctai_typedconstbuilder.get_dynstring_rec_name(st,winlikewidestring,strlength),srsym,srsymtable) then
|
||||||
|
internalerror(2014080406);
|
||||||
|
strrecdef:=trecorddef(ttypesym(srsym).typedef);
|
||||||
|
{ offset in the record of the the string data }
|
||||||
|
offset:=ctai_typedconstbuilder.get_string_symofs(st,winlikewidestring);
|
||||||
|
{ field corresponding to this offset }
|
||||||
|
field:=trecordsymtable(strrecdef.symtable).findfieldbyoffset(offset);
|
||||||
|
{ pointerdef to the string data array }
|
||||||
|
dataptrdef:=getpointerdef(field.vardef);
|
||||||
|
ftcb.queue_init(charptrdef);
|
||||||
|
ftcb.queue_addrn(dataptrdef,charptrdef);
|
||||||
|
ftcb.queue_subscriptn(strrecdef,field);
|
||||||
|
ftcb.queue_emit_asmsym(ll.lab,strrecdef);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{ since llvm doesn't support labels in the middle of structs, this
|
||||||
|
offset should never be 0 }
|
||||||
|
internalerror(2014080506);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ctai_typedconstbuilder:=tllvmtai_typedconstbuilder;
|
ctai_typedconstbuilder:=tllvmtai_typedconstbuilder;
|
||||||
|
ctypedconstbuilder:=tllvmasmlisttypedconstbuilder;
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
aasmbase,
|
aasmbase,
|
||||||
|
symtype,
|
||||||
node,ncon;
|
node,ncon;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -49,6 +50,8 @@ interface
|
|||||||
|
|
||||||
tcgstringconstnode = class(tstringconstnode)
|
tcgstringconstnode = class(tstringconstnode)
|
||||||
procedure pass_generate_code;override;
|
procedure pass_generate_code;override;
|
||||||
|
protected
|
||||||
|
procedure load_dynstring(const strpointerdef: tdef; const elementdef: tdef; const winlikewidestring: boolean); virtual;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
tcgsetconstnode = class(tsetconstnode)
|
tcgsetconstnode = class(tsetconstnode)
|
||||||
@ -77,7 +80,7 @@ implementation
|
|||||||
symconst,symdef,aasmtai,aasmdata,aasmcpu,defutil,
|
symconst,symdef,aasmtai,aasmdata,aasmcpu,defutil,
|
||||||
cpuinfo,cpubase,
|
cpuinfo,cpubase,
|
||||||
cgbase,cgobj,cgutils,
|
cgbase,cgobj,cgutils,
|
||||||
ncgutil,hlcgobj,symtype,cclasses,asmutils,tgobj
|
ncgutil,hlcgobj,cclasses,tgobj
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
@ -261,7 +264,6 @@ implementation
|
|||||||
lastlabel: tasmlabofs;
|
lastlabel: tasmlabofs;
|
||||||
pc: pchar;
|
pc: pchar;
|
||||||
l: longint;
|
l: longint;
|
||||||
href: treference;
|
|
||||||
pool: THashSet;
|
pool: THashSet;
|
||||||
entry: PHashSetItem;
|
entry: PHashSetItem;
|
||||||
winlikewidestring: boolean;
|
winlikewidestring: boolean;
|
||||||
@ -330,7 +332,7 @@ implementation
|
|||||||
InternalError(2008032301) { empty string should be handled above }
|
InternalError(2008032301) { empty string should be handled above }
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
lastlabel:=emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len,tstringdef(resultdef).encoding);
|
lastlabel:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len,tstringdef(resultdef).encoding,true);
|
||||||
{ because we hardcode the offset below due to it
|
{ because we hardcode the offset below due to it
|
||||||
not being stored in the hashset, check here }
|
not being stored in the hashset, check here }
|
||||||
if lastlabel.ofs<>ctai_typedconstbuilder.get_string_symofs(st_ansistring,false) then
|
if lastlabel.ofs<>ctai_typedconstbuilder.get_string_symofs(st_ansistring,false) then
|
||||||
@ -344,7 +346,7 @@ implementation
|
|||||||
InternalError(2008032302) { empty string should be handled above }
|
InternalError(2008032302) { empty string should be handled above }
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
lastlabel := emit_unicodestring_const(current_asmdata.AsmLists[al_typedconsts],
|
lastlabel:=ctai_typedconstbuilder.emit_unicodestring_const(current_asmdata.AsmLists[al_typedconsts],
|
||||||
value_str,
|
value_str,
|
||||||
tstringdef(resultdef).encoding,
|
tstringdef(resultdef).encoding,
|
||||||
winlikewidestring);
|
winlikewidestring);
|
||||||
@ -410,11 +412,8 @@ implementation
|
|||||||
if cst_type in [cst_ansistring, cst_widestring, cst_unicodestring] then
|
if cst_type in [cst_ansistring, cst_widestring, cst_unicodestring] then
|
||||||
begin
|
begin
|
||||||
location_reset(location, LOC_REGISTER, def_cgsize(strpointerdef));
|
location_reset(location, LOC_REGISTER, def_cgsize(strpointerdef));
|
||||||
reference_reset_symbol(href, lab_str,
|
|
||||||
ctai_typedconstbuilder.get_string_symofs(tstringdef(resultdef).stringtype,winlikewidestring),
|
|
||||||
const_align(strpointerdef.size));
|
|
||||||
location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,strpointerdef);
|
location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,strpointerdef);
|
||||||
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,elementdef,strpointerdef,href,location.register)
|
load_dynstring(strpointerdef, elementdef, winlikewidestring);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -424,6 +423,17 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcgstringconstnode.load_dynstring(const strpointerdef: tdef; const elementdef: tdef; const winlikewidestring: boolean);
|
||||||
|
var
|
||||||
|
href: treference;
|
||||||
|
begin
|
||||||
|
reference_reset_symbol(href, lab_str,
|
||||||
|
ctai_typedconstbuilder.get_string_symofs(tstringdef(resultdef).stringtype, winlikewidestring),
|
||||||
|
const_align(strpointerdef.size));
|
||||||
|
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList, elementdef, strpointerdef, href, location.register)
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TCGSETCONSTNODE
|
TCGSETCONSTNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
@ -29,7 +29,7 @@ interface
|
|||||||
globtype,cclasses,constexp,
|
globtype,cclasses,constexp,
|
||||||
aasmbase,aasmdata,aasmtai,aasmcnst,
|
aasmbase,aasmdata,aasmtai,aasmcnst,
|
||||||
node,nbas,
|
node,nbas,
|
||||||
symtype, symbase, symdef,symsym;
|
symconst, symtype, symbase, symdef,symsym;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -99,6 +99,8 @@ interface
|
|||||||
procedure tc_emit_setdef(def: tsetdef; var node: tnode);override;
|
procedure tc_emit_setdef(def: tsetdef; var node: tnode);override;
|
||||||
procedure tc_emit_enumdef(def: tenumdef; var node: tnode);override;
|
procedure tc_emit_enumdef(def: tenumdef; var node: tnode);override;
|
||||||
procedure tc_emit_stringdef(def: tstringdef; var node: tnode);override;
|
procedure tc_emit_stringdef(def: tstringdef; var node: tnode);override;
|
||||||
|
|
||||||
|
procedure tc_emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);virtual;
|
||||||
public
|
public
|
||||||
constructor create(sym: tstaticvarsym);virtual;
|
constructor create(sym: tstaticvarsym);virtual;
|
||||||
procedure parse_into_asmlist;
|
procedure parse_into_asmlist;
|
||||||
@ -143,7 +145,7 @@ uses
|
|||||||
SysUtils,
|
SysUtils,
|
||||||
systems,tokens,verbose,
|
systems,tokens,verbose,
|
||||||
cutils,globals,widestr,scanner,
|
cutils,globals,widestr,scanner,
|
||||||
symconst,symtable,
|
symtable,
|
||||||
aasmcpu,defutil,defcmp,
|
aasmcpu,defutil,defcmp,
|
||||||
{ pass 1 }
|
{ pass 1 }
|
||||||
htypechk,procinfo,
|
htypechk,procinfo,
|
||||||
@ -152,7 +154,7 @@ uses
|
|||||||
pbase,pexpr,pdecvar,
|
pbase,pexpr,pdecvar,
|
||||||
{ codegen }
|
{ codegen }
|
||||||
cpuinfo,cgbase,dbgbase,
|
cpuinfo,cgbase,dbgbase,
|
||||||
wpobase,asmutils
|
wpobase
|
||||||
;
|
;
|
||||||
|
|
||||||
{$maxfpuregisters 0}
|
{$maxfpuregisters 0}
|
||||||
@ -444,6 +446,12 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tasmlisttypedconstbuilder.tc_emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);
|
||||||
|
begin
|
||||||
|
ftcb.emit_tai(Tai_const.Create_sym_offset(ll.lab,ll.ofs),charptrdef);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tasmlisttypedconstbuilder.tc_emit_stringdef(def: tstringdef; var node: tnode);
|
procedure tasmlisttypedconstbuilder.tc_emit_stringdef(def: tstringdef; var node: tnode);
|
||||||
var
|
var
|
||||||
strlength : aint;
|
strlength : aint;
|
||||||
@ -551,8 +559,8 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
|||||||
ll.ofs:=0;
|
ll.ofs:=0;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ll:=emit_ansistring_const(current_asmdata.asmlists[al_const],strval,strlength,def.encoding);
|
ll:=ctai_typedconstbuilder.emit_ansistring_const(current_asmdata.asmlists[al_const],strval,strlength,def.encoding,true);
|
||||||
ftcb.emit_tai(Tai_const.Create_sym_offset(ll.lab,ll.ofs),getpointerdef(cansichartype));
|
tc_emit_string_offset(ll,strlength,def.stringtype,false,charpointertype);
|
||||||
end;
|
end;
|
||||||
st_unicodestring,
|
st_unicodestring,
|
||||||
st_widestring:
|
st_widestring:
|
||||||
@ -566,7 +574,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
winlike:=(def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags);
|
winlike:=(def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags);
|
||||||
ll:=emit_unicodestring_const(current_asmdata.asmlists[al_const],
|
ll:=ctai_typedconstbuilder.emit_unicodestring_const(current_asmdata.asmlists[al_const],
|
||||||
strval,
|
strval,
|
||||||
def.encoding,
|
def.encoding,
|
||||||
winlike);
|
winlike);
|
||||||
@ -588,7 +596,7 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
|
|||||||
Include(tcsym.varoptions,vo_force_finalize);
|
Include(tcsym.varoptions,vo_force_finalize);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ftcb.emit_tai(Tai_const.Create_sym_offset(ll.lab,ll.ofs),getpointerdef(cwidechartype));
|
tc_emit_string_offset(ll,strlength,def.stringtype,winlike,widecharpointertype);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(200107081);
|
internalerror(200107081);
|
||||||
|
Loading…
Reference in New Issue
Block a user