123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- {
- $Id$
- Copyright (c) 2002 by Florian Klaempfl
- Generic calling convention handling
- 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 parabase;
- {$i fpcdefs.inc}
- interface
- uses
- cclasses,globtype,
- cpubase,cgbase;
- type
- { tparamlocation describes where a parameter for a procedure is stored.
- References are given from the caller's point of view. The usual
- TLocation isn't used, because contains a lot of unnessary fields.
- }
- PCGParaLocation = ^TCGParaLocation;
- TCGParaLocation = record
- Next : PCGParaLocation;
- Size : TCGSize; { size of this location }
- Loc : TCGLoc;
- case TCGLoc of
- LOC_REFERENCE : (reference : tparareference);
- LOC_FPUREGISTER,
- LOC_CFPUREGISTER,
- LOC_MMREGISTER,
- LOC_CMMREGISTER,
- LOC_REGISTER,
- LOC_CREGISTER : (register : tregister);
- end;
- TCGPara = object
- Alignment : ShortInt;
- Size : TCGSize; { Size of the parameter included in all locations }
- Location : PCGParalocation;
- constructor init;
- destructor done;
- procedure reset;
- procedure check_simple_location;
- function add_location:pcgparalocation;
- procedure get_location(var newloc:tlocation);
- end;
- tvarargsinfo = (
- va_uses_float_reg
- );
- tvarargspara = class(tlinkedlist)
- varargsinfo : set of tvarargsinfo;
- {$ifdef x86_64}
- { x86_64 requires %al to contain the no. SSE regs passed }
- mmregsused : longint;
- {$endif x86_64}
- end;
- implementation
- uses
- systems,verbose;
- {****************************************************************************
- TCGPara
- ****************************************************************************}
- constructor tcgpara.init;
- begin
- alignment:=0;
- size:=OS_NO;
- location:=nil;
- end;
- destructor tcgpara.done;
- begin
- reset;
- end;
- procedure tcgpara.reset;
- var
- hlocation : pcgparalocation;
- begin
- while assigned(location) do
- begin
- hlocation:=location^.next;
- dispose(location);
- location:=hlocation;
- end;
- alignment:=0;
- size:=OS_NO;
- end;
- function tcgpara.add_location:pcgparalocation;
- var
- prevlocation,
- hlocation : pcgparalocation;
- begin
- prevlocation:=nil;
- hlocation:=location;
- while assigned(hlocation) do
- begin
- prevlocation:=hlocation;
- hlocation:=hlocation^.next;
- end;
- new(hlocation);
- Fillchar(hlocation^,sizeof(tcgparalocation),0);
- if assigned(prevlocation) then
- prevlocation^.next:=hlocation
- else
- location:=hlocation;
- result:=hlocation;
- end;
- procedure tcgpara.check_simple_location;
- begin
- if not assigned(location) then
- internalerror(200408161);
- if assigned(location^.next) then
- internalerror(200408162);
- end;
- procedure tcgpara.get_location(var newloc:tlocation);
- begin
- if not assigned(location) then
- internalerror(200408205);
- fillchar(newloc,sizeof(newloc),0);
- newloc.loc:=location^.loc;
- newloc.size:=size;
- case location^.loc of
- LOC_REGISTER :
- begin
- {$ifndef cpu64bit}
- if size in [OS_64,OS_S64] then
- begin
- if not assigned(location^.next) then
- internalerror(200408206);
- if (location^.next^.loc<>LOC_REGISTER) then
- internalerror(200408207);
- if (target_info.endian = ENDIAN_BIG) then
- begin
- newloc.registerhigh:=location^.register;
- newloc.registerlow:=location^.next^.register;
- end
- else
- begin
- newloc.registerlow:=location^.register;
- newloc.registerhigh:=location^.next^.register;
- end;
- end
- else
- {$endif}
- newloc.register:=location^.register;
- end;
- LOC_FPUREGISTER,
- LOC_MMREGISTER :
- newloc.register:=location^.register;
- LOC_REFERENCE :
- begin
- newloc.reference.base:=location^.reference.index;
- newloc.reference.offset:=location^.reference.offset;
- end;
- end;
- end;
- end.
- {
- $Log$
- Revision 1.2 2004-09-21 17:25:12 peter
- * paraloc branch merged
- Revision 1.1.2.2 2004/09/14 19:09:37 jonas
- * fixed typo in IE check
- Revision 1.1.2.1 2004/09/02 15:47:58 peter
- * missing file
- }
|