fpc/compiler/i8086/symcpu.pas
nickysn 36d63b953e + added an i8086 specific boolean property is_huge to the tarraydef. For now it
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 -
2014-07-26 13:27:46 +00:00

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.