mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-06 13:38:30 +02:00

will only be used for indexing huge pointers (i.e. only huge arrays with the ado_IsConvertedPointer array option will be supported). In the distant future, regular huge arrays may be supported as well (but that would require substantially more work, including adding hugeness support to other structures such as records, objects and classes, so I'm not planning on doing it anytime soon). git-svn-id: trunk@28270 -
459 lines
12 KiB
ObjectPascal
459 lines
12 KiB
ObjectPascal
{
|
|
Copyright (c) 2014 by Florian Klaempfl
|
|
|
|
Symbol table overrides for i8086
|
|
|
|
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 symcpu;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
globtype,
|
|
symconst,symtype,symdef,symsym,symx86,symi86;
|
|
|
|
type
|
|
{ defs }
|
|
tcpufiledef = class(tfiledef)
|
|
end;
|
|
tcpufiledefclass = class of tcpufiledef;
|
|
|
|
tcpuvariantdef = class(tvariantdef)
|
|
end;
|
|
tcpuvariantdefclass = class of tcpuvariantdef;
|
|
|
|
tcpuformaldef = class(tformaldef)
|
|
end;
|
|
tcpuformaldefclass = class of tcpuformaldef;
|
|
|
|
tcpuforwarddef = class(tforwarddef)
|
|
end;
|
|
tcpuforwarddefclass = class of tcpuforwarddef;
|
|
|
|
tcpuundefineddef = class(tundefineddef)
|
|
end;
|
|
tcpuundefineddefclass = class of tcpuundefineddef;
|
|
|
|
tcpuerrordef = class(terrordef)
|
|
end;
|
|
tcpuerrordefclass = class of tcpuerrordef;
|
|
|
|
tcpupointerdef = class(tx86pointerdef)
|
|
class function default_x86_data_pointer_type: tx86pointertyp; override;
|
|
function pointer_arithmetic_int_type:tdef; override;
|
|
function pointer_subtraction_result_type:tdef; override;
|
|
end;
|
|
tcpupointerdefclass = class of tcpupointerdef;
|
|
|
|
tcpurecorddef = class(trecorddef)
|
|
end;
|
|
tcpurecorddefclass = class of tcpurecorddef;
|
|
|
|
tcpuimplementedinterface = class(timplementedinterface)
|
|
end;
|
|
tcpuimplementedinterfaceclass = class of tcpuimplementedinterface;
|
|
|
|
tcpuobjectdef = class(tobjectdef)
|
|
end;
|
|
tcpuobjectdefclass = class of tcpuobjectdef;
|
|
|
|
tcpuclassrefdef = class(tclassrefdef)
|
|
end;
|
|
tcpuclassrefdefclass = class of tcpuclassrefdef;
|
|
|
|
{ tcpuarraydef }
|
|
|
|
tcpuarraydef = class(tarraydef)
|
|
private
|
|
huge: Boolean;
|
|
protected
|
|
procedure ppuload_platform(ppufile: tcompilerppufile); override;
|
|
procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
|
|
public
|
|
constructor create_from_pointer(def:tpointerdef);override;
|
|
function getcopy: tstoreddef; override;
|
|
function GetTypeName:string;override;
|
|
property is_huge: Boolean read huge write huge;
|
|
end;
|
|
tcpuarraydefclass = class of tcpuarraydef;
|
|
|
|
tcpuorddef = class(torddef)
|
|
end;
|
|
tcpuorddefclass = class of tcpuorddef;
|
|
|
|
tcpufloatdef = class(tfloatdef)
|
|
end;
|
|
tcpufloatdefclass = class of tcpufloatdef;
|
|
|
|
{ tcpuprocvardef }
|
|
|
|
tcpuprocvardef = class(ti86procvardef)
|
|
constructor create(level:byte);override;
|
|
function is_far:boolean;
|
|
end;
|
|
tcpuprocvardefclass = class of tcpuprocvardef;
|
|
|
|
{ tcpuprocdef }
|
|
|
|
tcpuprocdef = class(ti86procdef)
|
|
private
|
|
{ returns whether the function is far by default, i.e. whether it would be
|
|
far if _all_ of the following conditions are true:
|
|
- we're in a far code memory model
|
|
- it has no 'near' or 'far' specifiers
|
|
- it is compiled in a $F- state }
|
|
function default_far:boolean;
|
|
public
|
|
constructor create(level:byte);override;
|
|
function address_type:tdef;override;
|
|
procedure declared_far;override;
|
|
procedure declared_near;override;
|
|
function is_far:boolean;
|
|
end;
|
|
tcpuprocdefclass = class of tcpuprocdef;
|
|
|
|
tcpustringdef = class(tstringdef)
|
|
end;
|
|
tcpustringdefclass = class of tcpustringdef;
|
|
|
|
tcpuenumdef = class(tenumdef)
|
|
end;
|
|
tcpuenumdefclass = class of tcpuenumdef;
|
|
|
|
tcpusetdef = class(tsetdef)
|
|
end;
|
|
tcpusetdefclass = class of tcpusetdef;
|
|
|
|
{ syms }
|
|
tcpulabelsym = class(tlabelsym)
|
|
end;
|
|
tcpulabelsymclass = class of tcpulabelsym;
|
|
|
|
tcpuunitsym = class(tunitsym)
|
|
end;
|
|
tcpuunitsymclass = class of tcpuunitsym;
|
|
|
|
tcpunamespacesym = class(tnamespacesym)
|
|
end;
|
|
tcpunamespacesymclass = class of tcpunamespacesym;
|
|
|
|
tcpuprocsym = class(tprocsym)
|
|
end;
|
|
tcpuprocsymclass = class of tcpuprocsym;
|
|
|
|
tcputypesym = class(ttypesym)
|
|
end;
|
|
tcpuypesymclass = class of tcputypesym;
|
|
|
|
tcpufieldvarsym = class(tfieldvarsym)
|
|
end;
|
|
tcpufieldvarsymclass = class of tcpufieldvarsym;
|
|
|
|
tcpulocalvarsym = class(tlocalvarsym)
|
|
end;
|
|
tcpulocalvarsymclass = class of tcpulocalvarsym;
|
|
|
|
tcpuparavarsym = class(tparavarsym)
|
|
end;
|
|
tcpuparavarsymclass = class of tcpuparavarsym;
|
|
|
|
tcpustaticvarsym = class(tstaticvarsym)
|
|
end;
|
|
tcpustaticvarsymclass = class of tcpustaticvarsym;
|
|
|
|
tcpuabsolutevarsym = class(ti86absolutevarsym)
|
|
protected
|
|
procedure ppuload_platform(ppufile: tcompilerppufile); override;
|
|
procedure ppuwrite_platform(ppufile: tcompilerppufile); override;
|
|
public
|
|
addrsegment : aword;
|
|
end;
|
|
tcpuabsolutevarsymclass = class of tcpuabsolutevarsym;
|
|
|
|
tcpupropertysym = class(tpropertysym)
|
|
end;
|
|
tcpupropertysymclass = class of tcpupropertysym;
|
|
|
|
tcpuconstsym = class(tconstsym)
|
|
end;
|
|
tcpuconstsymclass = class of tcpuconstsym;
|
|
|
|
tcpuenumsym = class(tenumsym)
|
|
end;
|
|
tcpuenumsymclass = class of tcpuenumsym;
|
|
|
|
tcpusyssym = class(tsyssym)
|
|
end;
|
|
tcpusyssymclass = class of tcpusyssym;
|
|
|
|
|
|
const
|
|
pbestrealtype : ^tdef = @s80floattype;
|
|
|
|
|
|
function is_proc_far(p: tabstractprocdef): boolean;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
globals, cpuinfo, verbose;
|
|
|
|
|
|
function is_proc_far(p: tabstractprocdef): boolean;
|
|
begin
|
|
if p is tcpuprocdef then
|
|
result:=tcpuprocdef(p).is_far
|
|
else if p is tcpuprocvardef then
|
|
result:=tcpuprocvardef(p).is_far
|
|
else
|
|
internalerror(2014041301);
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
tcpuarraydef
|
|
****************************************************************************}
|
|
|
|
constructor tcpuarraydef.create_from_pointer(def: tpointerdef);
|
|
begin
|
|
if tcpupointerdef(def).x86pointertyp=x86pt_huge then
|
|
begin
|
|
huge:=true;
|
|
{ use -1 so that the elecount will not overflow }
|
|
self.create(0,high(asizeint)-1,s32inttype);
|
|
arrayoptions:=[ado_IsConvertedPointer];
|
|
setelementdef(def.pointeddef);
|
|
end
|
|
else
|
|
begin
|
|
huge:=false;
|
|
inherited create_from_pointer(def);
|
|
end;
|
|
end;
|
|
|
|
|
|
function tcpuarraydef.getcopy: tstoreddef;
|
|
begin
|
|
result:=inherited;
|
|
tcpuarraydef(result).huge:=huge;
|
|
end;
|
|
|
|
|
|
function tcpuarraydef.GetTypeName: string;
|
|
begin
|
|
Result:=inherited;
|
|
if is_huge then
|
|
Result:='Huge '+Result;
|
|
end;
|
|
|
|
|
|
procedure tcpuarraydef.ppuload_platform(ppufile: tcompilerppufile);
|
|
begin
|
|
inherited;
|
|
huge:=(ppufile.getbyte<>0);
|
|
end;
|
|
|
|
|
|
procedure tcpuarraydef.ppuwrite_platform(ppufile: tcompilerppufile);
|
|
begin
|
|
inherited;
|
|
ppufile.putbyte(byte(huge));
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
tcpuprocdef
|
|
****************************************************************************}
|
|
|
|
constructor tcpuprocdef.create(level: byte);
|
|
begin
|
|
inherited create(level);
|
|
if (current_settings.x86memorymodel in x86_far_code_models) and
|
|
((cs_huge_code in current_settings.moduleswitches) or
|
|
(cs_force_far_calls in current_settings.localswitches)) then
|
|
procoptions:=procoptions+[po_far];
|
|
end;
|
|
|
|
|
|
function tcpuprocdef.address_type: tdef;
|
|
begin
|
|
if is_far then
|
|
result:=voidfarpointertype
|
|
else
|
|
result:=voidnearpointertype;
|
|
end;
|
|
|
|
|
|
procedure tcpuprocdef.declared_far;
|
|
begin
|
|
if current_settings.x86memorymodel in x86_far_code_models then
|
|
include(procoptions,po_far)
|
|
else
|
|
inherited declared_far;
|
|
end;
|
|
|
|
|
|
procedure tcpuprocdef.declared_near;
|
|
begin
|
|
if (current_settings.x86memorymodel in x86_far_code_models) and
|
|
not (cs_huge_code in current_settings.moduleswitches) then
|
|
exclude(procoptions,po_far)
|
|
else
|
|
inherited declared_near;
|
|
end;
|
|
|
|
|
|
function tcpuprocdef.default_far: boolean;
|
|
begin
|
|
if proctypeoption in [potype_proginit,potype_unitinit,potype_unitfinalize,
|
|
potype_constructor,potype_destructor,
|
|
potype_class_constructor,potype_class_destructor,
|
|
potype_propgetter,potype_propsetter] then
|
|
exit(true);
|
|
if (procoptions*[po_classmethod,po_virtualmethod,po_abstractmethod,
|
|
po_finalmethod,po_staticmethod,po_overridingmethod,
|
|
po_external,po_public,po_interrupt])<>[] then
|
|
exit(true);
|
|
if is_methodpointer then
|
|
exit(true);
|
|
result:=not (visibility in [vis_private,vis_hidden]);
|
|
end;
|
|
|
|
|
|
function tcpuprocdef.is_far: boolean;
|
|
begin
|
|
result:=(current_settings.x86memorymodel in x86_far_code_models) and
|
|
((po_far in procoptions) or default_far);
|
|
end;
|
|
|
|
{****************************************************************************
|
|
tcpuprocvardef
|
|
****************************************************************************}
|
|
|
|
constructor tcpuprocvardef.create(level: byte);
|
|
begin
|
|
inherited create(level);
|
|
{ procvars are always far in the far code memory models }
|
|
if current_settings.x86memorymodel in x86_far_code_models then
|
|
procoptions:=procoptions+[po_far];
|
|
end;
|
|
|
|
|
|
function tcpuprocvardef.is_far: boolean;
|
|
begin
|
|
{ procvars are always far in the far code memory models }
|
|
result:=current_settings.x86memorymodel in x86_far_code_models;
|
|
end;
|
|
|
|
{****************************************************************************
|
|
tcpupointerdef
|
|
****************************************************************************}
|
|
|
|
class function tcpupointerdef.default_x86_data_pointer_type: tx86pointertyp;
|
|
begin
|
|
if current_settings.x86memorymodel in x86_far_data_models then
|
|
result:=x86pt_far
|
|
else
|
|
result:=inherited;
|
|
end;
|
|
|
|
|
|
function tcpupointerdef.pointer_arithmetic_int_type:tdef;
|
|
begin
|
|
if x86pointertyp=x86pt_huge then
|
|
result:=s32inttype
|
|
else
|
|
result:=inherited;
|
|
end;
|
|
|
|
|
|
function tcpupointerdef.pointer_subtraction_result_type:tdef;
|
|
begin
|
|
case x86pointertyp of
|
|
x86pt_huge:
|
|
result:=s32inttype;
|
|
x86pt_far:
|
|
result:=u16inttype;
|
|
else
|
|
result:=inherited;
|
|
end;
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
tcpuabsolutevarsym
|
|
****************************************************************************}
|
|
|
|
procedure tcpuabsolutevarsym.ppuload_platform(ppufile: tcompilerppufile);
|
|
begin
|
|
inherited;
|
|
if absseg then
|
|
addrsegment:=ppufile.getaword;
|
|
end;
|
|
|
|
|
|
procedure tcpuabsolutevarsym.ppuwrite_platform(ppufile: tcompilerppufile);
|
|
begin
|
|
inherited;
|
|
if absseg then
|
|
ppufile.putaword(addrsegment);
|
|
end;
|
|
|
|
begin
|
|
{ used tdef classes }
|
|
cfiledef:=tcpufiledef;
|
|
cvariantdef:=tcpuvariantdef;
|
|
cformaldef:=tcpuformaldef;
|
|
cforwarddef:=tcpuforwarddef;
|
|
cundefineddef:=tcpuundefineddef;
|
|
cerrordef:=tcpuerrordef;
|
|
cpointerdef:=tcpupointerdef;
|
|
crecorddef:=tcpurecorddef;
|
|
cimplementedinterface:=tcpuimplementedinterface;
|
|
cobjectdef:=tcpuobjectdef;
|
|
cclassrefdef:=tcpuclassrefdef;
|
|
carraydef:=tcpuarraydef;
|
|
corddef:=tcpuorddef;
|
|
cfloatdef:=tcpufloatdef;
|
|
cprocvardef:=tcpuprocvardef;
|
|
cprocdef:=tcpuprocdef;
|
|
cstringdef:=tcpustringdef;
|
|
cenumdef:=tcpuenumdef;
|
|
csetdef:=tcpusetdef;
|
|
|
|
{ used tsym classes }
|
|
clabelsym:=tcpulabelsym;
|
|
cunitsym:=tcpuunitsym;
|
|
cnamespacesym:=tcpunamespacesym;
|
|
cprocsym:=tcpuprocsym;
|
|
ctypesym:=tcputypesym;
|
|
cfieldvarsym:=tcpufieldvarsym;
|
|
clocalvarsym:=tcpulocalvarsym;
|
|
cparavarsym:=tcpuparavarsym;
|
|
cstaticvarsym:=tcpustaticvarsym;
|
|
cabsolutevarsym:=tcpuabsolutevarsym;
|
|
cpropertysym:=tcpupropertysym;
|
|
cconstsym:=tcpuconstsym;
|
|
cenumsym:=tcpuenumsym;
|
|
csyssym:=tcpusyssym;
|
|
end.
|
|
|