mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 19:29:28 +02:00
216 lines
6.1 KiB
ObjectPascal
216 lines
6.1 KiB
ObjectPascal
{
|
|
Copyright (c) 1998-2004 by Florian Klaempfl
|
|
|
|
Some basic types and constants for the code generation
|
|
|
|
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.
|
|
|
|
****************************************************************************
|
|
}
|
|
{ This unit exports some helper routines which are used across the code generator }
|
|
unit cgutils;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
globtype,
|
|
cclasses,
|
|
aasmbase,
|
|
cpubase,cgbase;
|
|
|
|
type
|
|
{ reference record, reordered for best alignment }
|
|
preference = ^treference;
|
|
treference = record
|
|
offset : aint;
|
|
symbol,
|
|
relsymbol : tasmsymbol;
|
|
segment,
|
|
base,
|
|
index : tregister;
|
|
refaddr : trefaddr;
|
|
scalefactor : byte;
|
|
{$ifdef arm}
|
|
symboldata : tlinkedlistitem;
|
|
signindex : shortint;
|
|
shiftimm : byte;
|
|
addressmode : taddressmode;
|
|
shiftmode : tshiftmode;
|
|
{$endif arm}
|
|
{$ifdef m68k}
|
|
{ indexed increment and decrement mode }
|
|
{ (An)+ and -(An) }
|
|
direction : tdirection;
|
|
{$endif m68k}
|
|
{$ifdef SUPPORT_UNALIGNED}
|
|
alignment : byte;
|
|
{$endif SUPPORT_UNALIGNED}
|
|
end;
|
|
|
|
tlocation = record
|
|
loc : TCGLoc;
|
|
size : TCGSize;
|
|
case TCGLoc of
|
|
LOC_FLAGS : (resflags : tresflags);
|
|
LOC_CONSTANT : (
|
|
case longint of
|
|
{$ifdef FPC_BIG_ENDIAN}
|
|
1 : (_valuedummy,value : aint);
|
|
{$else FPC_BIG_ENDIAN}
|
|
1 : (value : aint);
|
|
{$endif FPC_BIG_ENDIAN}
|
|
2 : (value64 : Int64);
|
|
);
|
|
LOC_CREFERENCE,
|
|
LOC_REFERENCE : (reference : treference);
|
|
{ segment in reference at the same place as in loc_register }
|
|
LOC_REGISTER,
|
|
LOC_CREGISTER : (
|
|
case longint of
|
|
1 : (register : tregister;
|
|
{$ifdef m68k}
|
|
{ some m68k OSes require that the result is returned in d0 and a0
|
|
the second location must be stored here }
|
|
registeralias : tregister;
|
|
{$endif m68k}
|
|
);
|
|
{$ifndef cpu64bit}
|
|
{ overlay a 64 Bit register type }
|
|
2 : (register64 : tregister64);
|
|
{$endif cpu64bit}
|
|
);
|
|
LOC_SUBSETREG,
|
|
LOC_CSUBSETREG : (
|
|
subsetreg : tregister;
|
|
startbit: byte;
|
|
subsetregsize: tcgsize;
|
|
);
|
|
end;
|
|
|
|
|
|
{ trerefence handling }
|
|
|
|
{# Clear to zero a treference }
|
|
procedure reference_reset(var ref : treference);
|
|
{# Clear to zero a treference, and set is base address
|
|
to base register.
|
|
}
|
|
procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
|
|
procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
|
|
{ This routine verifies if two references are the same, and
|
|
if so, returns TRUE, otherwise returns false.
|
|
}
|
|
function references_equal(const sref,dref : treference) : boolean;
|
|
|
|
{ tlocation handling }
|
|
|
|
procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize);
|
|
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
|
procedure location_swap(var destloc,sourceloc : tlocation);
|
|
|
|
|
|
{ allocate room for parameters on the stack in the entry code? }
|
|
function use_fixed_stack: boolean;
|
|
|
|
implementation
|
|
|
|
uses
|
|
systems;
|
|
|
|
{****************************************************************************
|
|
TReference
|
|
****************************************************************************}
|
|
|
|
procedure reference_reset(var ref : treference);
|
|
begin
|
|
FillChar(ref,sizeof(treference),0);
|
|
{$ifdef arm}
|
|
ref.signindex:=1;
|
|
{$endif arm}
|
|
end;
|
|
|
|
|
|
procedure reference_reset_base(var ref : treference;base : tregister;offset : longint);
|
|
begin
|
|
reference_reset(ref);
|
|
ref.base:=base;
|
|
ref.offset:=offset;
|
|
end;
|
|
|
|
|
|
procedure reference_reset_symbol(var ref : treference;sym : tasmsymbol;offset : longint);
|
|
begin
|
|
reference_reset(ref);
|
|
ref.symbol:=sym;
|
|
ref.offset:=offset;
|
|
end;
|
|
|
|
|
|
function references_equal(const sref,dref : treference):boolean;
|
|
begin
|
|
references_equal:=CompareByte(sref,dref,sizeof(treference))=0;
|
|
end;
|
|
|
|
|
|
{****************************************************************************
|
|
TLocation
|
|
****************************************************************************}
|
|
|
|
procedure location_reset(var l : tlocation;lt:TCGLoc;lsize:TCGSize);
|
|
begin
|
|
FillChar(l,sizeof(tlocation),0);
|
|
l.loc:=lt;
|
|
l.size:=lsize;
|
|
{$ifdef arm}
|
|
if l.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
|
l.reference.signindex:=1;
|
|
{$endif arm}
|
|
end;
|
|
|
|
|
|
procedure location_copy(var destloc:tlocation; const sourceloc : tlocation);
|
|
begin
|
|
destloc:=sourceloc;
|
|
end;
|
|
|
|
|
|
procedure location_swap(var destloc,sourceloc : tlocation);
|
|
var
|
|
swapl : tlocation;
|
|
begin
|
|
swapl := destloc;
|
|
destloc := sourceloc;
|
|
sourceloc := swapl;
|
|
end;
|
|
|
|
|
|
function use_fixed_stack: boolean;
|
|
begin
|
|
{$ifdef i386}
|
|
result := (target_info.system = system_i386_darwin);
|
|
{$else i386}
|
|
{$ifdef cputargethasfixedstack}
|
|
result := true;
|
|
{$else cputargethasfixedstack}
|
|
result := false;
|
|
{$endif cputargethasfixedstack}
|
|
{$endif i386}
|
|
end;
|
|
|
|
end.
|
|
|