mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 19:19:19 +02:00
* Internal error fixed, but usually i386 parameter model used
This commit is contained in:
parent
1c642c2002
commit
de41a87b82
@ -9,7 +9,7 @@
|
|||||||
{
|
{
|
||||||
$Id$
|
$Id$
|
||||||
|
|
||||||
Copyright (c) 1998-2000 by Florian Klaempfl
|
Copyright (c) 1998-2000 by Florian Klaempfl
|
||||||
|
|
||||||
This program is free software;you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -36,7 +36,7 @@ USES
|
|||||||
node,symconst;
|
node,symconst;
|
||||||
TYPE
|
TYPE
|
||||||
tcgSPARC=CLASS(tcg)
|
tcgSPARC=CLASS(tcg)
|
||||||
FreeParamRegSet:TRegisterSet;
|
FreeParamRegSet:TRegisterSet;
|
||||||
{This method is used to pass a parameter, which is located in a register, to a
|
{This method is used to pass a parameter, which is located in a register, to a
|
||||||
routine. It should give the parameter to the routine, as required by the
|
routine. It should give the parameter to the routine, as required by the
|
||||||
specific processor ABI. It is overriden for each CPU target.
|
specific processor ABI. It is overriden for each CPU target.
|
||||||
@ -87,7 +87,7 @@ specific processor ABI. It is overriden for each CPU target.
|
|||||||
procedure g_concatcopy(list:TAasmOutput;CONST source,dest:TReference;len:aword;delsource,loadref:boolean);override;
|
procedure g_concatcopy(list:TAasmOutput;CONST source,dest:TReference;len:aword;delsource,loadref:boolean);override;
|
||||||
class function reg_cgsize(CONST reg:tregister):tcgsize;override;
|
class function reg_cgsize(CONST reg:tregister):tcgsize;override;
|
||||||
PRIVATE
|
PRIVATE
|
||||||
function IsSimpleRef(const ref:treference):boolean;
|
function IsSimpleRef(const ref:treference):boolean;
|
||||||
procedure sizes2load(s1:tcgsize;s2:topsize;var op:tasmop;var s3:topsize);
|
procedure sizes2load(s1:tcgsize;s2:topsize;var op:tasmop;var s3:topsize);
|
||||||
procedure floatload(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
|
procedure floatload(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
|
||||||
procedure floatstore(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
|
procedure floatstore(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
|
||||||
@ -127,41 +127,40 @@ procedure tcgSPARC.a_param_const(list:TAasmOutput;size:tcgsize;a:aword;CONST Loc
|
|||||||
List.Concat(taicpu.op_const(A_LD,S_L,a));
|
List.Concat(taicpu.op_const(A_LD,S_L,a));
|
||||||
END;
|
END;
|
||||||
procedure tcgSPARC.a_param_ref(list:TAasmOutput;size:tcgsize;const r:TReference;const LocPara:TParaLocation);
|
procedure tcgSPARC.a_param_ref(list:TAasmOutput;size:tcgsize;const r:TReference;const LocPara:TParaLocation);
|
||||||
var
|
var
|
||||||
ref: treference;
|
ref: treference;
|
||||||
tmpreg:TRegister;
|
tmpreg:TRegister;
|
||||||
begin
|
begin
|
||||||
if Size<>OS_32
|
case locpara.loc of
|
||||||
then
|
LOC_REGISTER,LOC_CREGISTER:
|
||||||
InternalError(2002100400);
|
a_load_ref_reg(list,size,r,locpara.register);
|
||||||
case locpara.loc of
|
LOC_REFERENCE:
|
||||||
LOC_REGISTER,LOC_CREGISTER:
|
begin
|
||||||
a_load_ref_reg(list,size,r,locpara.register);
|
{Code conventions need the parameters being allocated in %o6+92. See
|
||||||
LOC_REFERENCE:
|
comment on g_stack_frame}
|
||||||
begin
|
if locpara.sp_fixup<92
|
||||||
reference_reset(ref);
|
then
|
||||||
ref.base:=locpara.reference.index;
|
InternalError(2002081104);
|
||||||
ref.offset:=locpara.reference.offset;
|
reference_reset(ref);
|
||||||
tmpreg := get_scratch_reg_int(list);
|
ref.base:=locpara.reference.index;
|
||||||
a_load_ref_reg(list,size,r,tmpreg);
|
ref.offset:=locpara.reference.offset;
|
||||||
a_load_reg_ref(list,size,tmpreg,ref);
|
tmpreg := get_scratch_reg_int(list);
|
||||||
free_scratch_reg(list,tmpreg);
|
a_load_ref_reg(list,size,r,tmpreg);
|
||||||
end;
|
a_load_reg_ref(list,size,tmpreg,ref);
|
||||||
LOC_FPUREGISTER,LOC_CFPUREGISTER:
|
free_scratch_reg(list,tmpreg);
|
||||||
case size of
|
end;
|
||||||
OS_32:
|
LOC_FPUREGISTER,LOC_CFPUREGISTER:
|
||||||
a_loadfpu_ref_reg(list,OS_F32,r,locpara.register);
|
case size of
|
||||||
OS_64:
|
OS_32:
|
||||||
a_loadfpu_ref_reg(list,OS_F64,r,locpara.register);
|
a_loadfpu_ref_reg(list,OS_F32,r,locpara.register);
|
||||||
else
|
OS_64:
|
||||||
internalerror(2002072801);
|
a_loadfpu_ref_reg(list,OS_F64,r,locpara.register);
|
||||||
end;
|
else
|
||||||
else
|
internalerror(2002072801);
|
||||||
internalerror(2002081103);
|
end;
|
||||||
end;
|
else
|
||||||
if locpara.sp_fixup<>0
|
internalerror(2002081103);
|
||||||
then
|
end;
|
||||||
internalerror(2002081104);
|
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.a_paramaddr_ref(list:TAasmOutput;CONST r:TReference;CONST LocPara:TParaLocation);
|
procedure tcgSPARC.a_paramaddr_ref(list:TAasmOutput;CONST r:TReference;CONST LocPara:TParaLocation);
|
||||||
VAR
|
VAR
|
||||||
@ -229,39 +228,39 @@ procedure tcgSPARC.a_load_reg_ref(list:TAasmOutput;size:TCGSize;reg:tregister;CO
|
|||||||
list.concat(taicpu.op_reg_ref(A_LD,TCGSize2OpSize[size],reg,ref));
|
list.concat(taicpu.op_reg_ref(A_LD,TCGSize2OpSize[size],reg,ref));
|
||||||
END;
|
END;
|
||||||
procedure tcgSPARC.a_load_ref_reg(list:TAasmOutput;size:tcgsize;const ref:TReference;reg:tregister);
|
procedure tcgSPARC.a_load_ref_reg(list:TAasmOutput;size:tcgsize;const ref:TReference;reg:tregister);
|
||||||
var
|
var
|
||||||
op:tasmop;
|
op:tasmop;
|
||||||
s:topsize;
|
s:topsize;
|
||||||
begin
|
begin
|
||||||
sizes2load(size,S_L,op,s);
|
sizes2load(size,S_L,op,s);
|
||||||
list.concat(taicpu.op_ref_reg(op,s,ref,reg));
|
list.concat(taicpu.op_ref_reg(op,s,ref,reg));
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
|
procedure tcgSPARC.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
|
||||||
var
|
var
|
||||||
op:tasmop;
|
op:tasmop;
|
||||||
s:topsize;
|
s:topsize;
|
||||||
begin
|
begin
|
||||||
if(reg1<>reg2)or
|
if(reg1<>reg2)or
|
||||||
(tcgsize2size[tosize]<tcgsize2size[fromsize])or
|
(tcgsize2size[tosize]<tcgsize2size[fromsize])or
|
||||||
((tcgsize2size[tosize] = tcgsize2size[fromsize])and
|
((tcgsize2size[tosize] = tcgsize2size[fromsize])and
|
||||||
(tosize <> fromsize)and
|
(tosize <> fromsize)and
|
||||||
not(fromsize in [OS_32,OS_S32]))
|
not(fromsize in [OS_32,OS_S32]))
|
||||||
then
|
then
|
||||||
with list do
|
with list do
|
||||||
case fromsize of
|
case fromsize of
|
||||||
OS_8:
|
OS_8:
|
||||||
InternalError(2002100800);{concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,reg2,reg1,0,31-8+1,31));}
|
InternalError(2002100800);{concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,reg2,reg1,0,31-8+1,31));}
|
||||||
OS_S8:
|
OS_S8:
|
||||||
InternalError(2002100801);{concat(taicpu.op_reg_reg(A_EXTSB,reg2,reg1));}
|
InternalError(2002100801);{concat(taicpu.op_reg_reg(A_EXTSB,reg2,reg1));}
|
||||||
OS_16:
|
OS_16:
|
||||||
InternalError(2002100802);{concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,reg2,reg1,0,31-16+1,31));}
|
InternalError(2002100802);{concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,reg2,reg1,0,31-16+1,31));}
|
||||||
OS_S16:
|
OS_S16:
|
||||||
InternalError(2002100803);{concat(taicpu.op_reg_reg(A_EXTSH,reg2,reg1));}
|
InternalError(2002100803);{concat(taicpu.op_reg_reg(A_EXTSH,reg2,reg1));}
|
||||||
OS_32,OS_S32:
|
OS_32,OS_S32:
|
||||||
concat(taicpu.op_reg_reg_reg(A_OR,S_L,R_G0,reg1,reg2));
|
concat(taicpu.op_reg_reg_reg(A_OR,S_L,R_G0,reg1,reg2));
|
||||||
else internalerror(2002090901);
|
else internalerror(2002090901);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{ all fpu load routines expect that R_ST[0-7] means an fpu regvar and }
|
{ all fpu load routines expect that R_ST[0-7] means an fpu regvar and }
|
||||||
{ R_ST means "the current value at the top of the fpu stack" (JM) }
|
{ R_ST means "the current value at the top of the fpu stack" (JM) }
|
||||||
procedure tcgSPARC.a_loadfpu_reg_reg(list:TAasmOutput;reg1, reg2:tregister);
|
procedure tcgSPARC.a_loadfpu_reg_reg(list:TAasmOutput;reg1, reg2:tregister);
|
||||||
@ -801,57 +800,57 @@ procedure tcgSPARC.g_stackframe_entry(list:TAasmOutput;localsize:LongInt);
|
|||||||
again:tasmlabel;
|
again:tasmlabel;
|
||||||
begin
|
begin
|
||||||
{According the the SPARC ABI the standard stack frame must include :
|
{According the the SPARC ABI the standard stack frame must include :
|
||||||
* 16 word save for the in and local registers in case of overflow/underflow.
|
* 16 word save for the in and local registers in case of overflow/underflow.
|
||||||
this save area always must exist at the %o6+0,
|
this save area always must exist at the %o6+0,
|
||||||
* software conventions requires space for the aggregate return value pointer, even if the word is not used,
|
* software conventions requires space for the aggregate return value pointer, even if the word is not used,
|
||||||
* althogh the first six words of arguments reside in registers, the standard
|
* althogh the first six words of arguments reside in registers, the standard
|
||||||
stack frame reserves space for them. Arguments beond the sixth reside on the
|
stack frame reserves space for them. Arguments beond the sixth reside on the
|
||||||
stack as in the Intel architecture,
|
stack as in the Intel architecture,
|
||||||
* other areas depend on the compiler and the code being compiled. The
|
* other areas depend on the compiler and the code being compiled. The
|
||||||
standard calling sequence does not define a maximum stack frame size, nor does
|
standard calling sequence does not define a maximum stack frame size, nor does
|
||||||
it restrict how a language system uses the "unspecified" areas of the standard
|
it restrict how a language system uses the "unspecified" areas of the standard
|
||||||
stack frame.}
|
stack frame.}
|
||||||
Dec(LocalSize,(16+1+5)*4);
|
Dec(LocalSize,(16+1+5)*4);
|
||||||
{Althogh the SPARC architecture require only word alignment, software
|
{Althogh the SPARC architecture require only word alignment, software
|
||||||
convention and the operating system require every stack frame to be double word
|
convention and the operating system require every stack frame to be double word
|
||||||
aligned}
|
aligned}
|
||||||
LocalSize:=(LocalSize+3)and $FFFFFFFC;
|
LocalSize:=(LocalSize+3)and $FFFFFFFC;
|
||||||
{Execute the SAVE instruction to get a new register window and get a new stack
|
{Execute the SAVE instruction to get a new register window and get a new stack
|
||||||
frame. In the "SAVE %i6,size,%i6" the first %i6 is related to the state before
|
frame. In the "SAVE %i6,size,%i6" the first %i6 is related to the state before
|
||||||
execution of the SAVE instrucion so it is the caller %i6, when the %i6 after
|
execution of the SAVE instrucion so it is the caller %i6, when the %i6 after
|
||||||
execution of that instrucion is the called function stack pointer}
|
execution of that instrucion is the called function stack pointer}
|
||||||
with list do
|
with list do
|
||||||
concat(Taicpu.Op_reg_const_reg(A_SAVE,S_L,Stack_Pointer_Reg,localsize,Stack_Pointer_Reg));
|
concat(Taicpu.Op_reg_const_reg(A_SAVE,S_L,Stack_Pointer_Reg,localsize,Stack_Pointer_Reg));
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.g_restore_frame_pointer(list:TAasmOutput);
|
procedure tcgSPARC.g_restore_frame_pointer(list:TAasmOutput);
|
||||||
begin
|
begin
|
||||||
{This function intontionally does nothing as frame pointer is restored in the
|
{This function intontionally does nothing as frame pointer is restored in the
|
||||||
delay slot of the return instrucion done in g_return_from_proc}
|
delay slot of the return instrucion done in g_return_from_proc}
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.g_return_from_proc(list:TAasmOutput;parasize:aword);
|
procedure tcgSPARC.g_return_from_proc(list:TAasmOutput;parasize:aword);
|
||||||
var
|
var
|
||||||
RetReference:TReference;
|
RetReference:TReference;
|
||||||
begin
|
begin
|
||||||
{According to the SPARC ABI, the stack is cleared using the RESTORE instruction
|
{According to the SPARC ABI, the stack is cleared using the RESTORE instruction
|
||||||
which is genereted in the g_restore_frame_pointer. Notice that SPARC has no
|
which is genereted in the g_restore_frame_pointer. Notice that SPARC has no
|
||||||
RETURN instruction and that JMPL is used instead. The JMPL instrucion have one
|
RETURN instruction and that JMPL is used instead. The JMPL instrucion have one
|
||||||
delay slot, so an inversion is possible such as
|
delay slot, so an inversion is possible such as
|
||||||
JMPL %i6+8,%g0
|
JMPL %i6+8,%g0
|
||||||
RESTORE %g0,0,%g0
|
RESTORE %g0,0,%g0
|
||||||
If no inversion we can use just
|
If no inversion we can use just
|
||||||
RESTORE %g0,0,%g0
|
RESTORE %g0,0,%g0
|
||||||
JMPL %i6+8,%g0
|
JMPL %i6+8,%g0
|
||||||
NOP}
|
NOP}
|
||||||
with list do
|
with list do
|
||||||
begin
|
begin
|
||||||
{Return address is computed by adding 8 to the CALL address saved onto %i6}
|
{Return address is computed by adding 8 to the CALL address saved onto %i6}
|
||||||
reference_reset_base(RetReference,R_I7,8);
|
reference_reset_base(RetReference,R_I7,8);
|
||||||
concat(Taicpu.Op_ref_reg(A_JMPL,S_L,RetReference,R_G0));
|
concat(Taicpu.Op_ref_reg(A_JMPL,S_L,RetReference,R_G0));
|
||||||
{We use trivial restore in the delay slot of the JMPL instruction, as we
|
{We use trivial restore in the delay slot of the JMPL instruction, as we
|
||||||
already set result onto %i0}
|
already set result onto %i0}
|
||||||
concat(Taicpu.Op_reg_const_reg(A_RESTORE,S_L,R_G0,0,R_G0));
|
concat(Taicpu.Op_reg_const_reg(A_RESTORE,S_L,R_G0,0,R_G0));
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tregister);
|
procedure tcgSPARC.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tregister);
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -970,17 +969,17 @@ procedure tcgSPARC.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tr
|
|||||||
|
|
||||||
{ ************* concatcopy ************ }
|
{ ************* concatcopy ************ }
|
||||||
procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aword;delsource,loadref:boolean);
|
procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aword;delsource,loadref:boolean);
|
||||||
var
|
var
|
||||||
countreg: TRegister;
|
countreg: TRegister;
|
||||||
src, dst: TReference;
|
src, dst: TReference;
|
||||||
lab: tasmlabel;
|
lab: tasmlabel;
|
||||||
count, count2: aword;
|
count, count2: aword;
|
||||||
orgsrc, orgdst: boolean;
|
orgsrc, orgdst: boolean;
|
||||||
begin
|
begin
|
||||||
{$ifdef extdebug}
|
{$ifdef extdebug}
|
||||||
if len > high(longint)
|
if len > high(longint)
|
||||||
then
|
then
|
||||||
internalerror(2002072704);
|
internalerror(2002072704);
|
||||||
{$endif extdebug}
|
{$endif extdebug}
|
||||||
{ make sure short loads are handled as optimally as possible }
|
{ make sure short loads are handled as optimally as possible }
|
||||||
if not loadref then
|
if not loadref then
|
||||||
@ -1134,60 +1133,60 @@ function tcgSPARC.reg_cgsize(CONST reg:tregister):tcgsize;
|
|||||||
|
|
||||||
{***************** This is private property, keep out! :) *****************}
|
{***************** This is private property, keep out! :) *****************}
|
||||||
function TCgSparc.IsSimpleRef(const ref:treference):boolean;
|
function TCgSparc.IsSimpleRef(const ref:treference):boolean;
|
||||||
begin
|
begin
|
||||||
if(ref.base=R_NONE)and(ref.index <> R_NO)
|
if(ref.base=R_NONE)and(ref.index <> R_NO)
|
||||||
then
|
then
|
||||||
InternalError(2002100804);
|
InternalError(2002100804);
|
||||||
result :=not(assigned(ref.symbol))and
|
result :=not(assigned(ref.symbol))and
|
||||||
(((ref.index = R_NO) and
|
(((ref.index = R_NO) and
|
||||||
(ref.offset >= low(smallint)) and
|
(ref.offset >= low(smallint)) and
|
||||||
(ref.offset <= high(smallint))) or
|
(ref.offset <= high(smallint))) or
|
||||||
((ref.index <> R_NO) and
|
((ref.index <> R_NO) and
|
||||||
(ref.offset = 0)));
|
(ref.offset = 0)));
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.sizes2load(s1:tcgsize;s2:topsize;var op:tasmop;var s3:topsize);
|
procedure tcgSPARC.sizes2load(s1:tcgsize;s2:topsize;var op:tasmop;var s3:topsize);
|
||||||
begin
|
begin
|
||||||
case s2 of
|
case s2 of
|
||||||
S_B:
|
S_B:
|
||||||
if S1 in [OS_8,OS_S8]
|
if S1 in [OS_8,OS_S8]
|
||||||
then
|
then
|
||||||
s3 := S_B
|
s3 := S_B
|
||||||
else
|
else
|
||||||
internalerror(200109221);
|
internalerror(200109221);
|
||||||
S_W:
|
S_W:
|
||||||
case s1 of
|
case s1 of
|
||||||
OS_8,OS_S8:
|
OS_8,OS_S8:
|
||||||
s3 := S_BW;
|
s3 := S_BW;
|
||||||
OS_16,OS_S16:
|
OS_16,OS_S16:
|
||||||
s3 := S_W;
|
s3 := S_W;
|
||||||
else
|
else
|
||||||
internalerror(200109222);
|
internalerror(200109222);
|
||||||
end;
|
end;
|
||||||
S_L:
|
S_L:
|
||||||
case s1 of
|
case s1 of
|
||||||
OS_8,OS_S8:
|
OS_8,OS_S8:
|
||||||
s3 := S_BL;
|
s3 := S_BL;
|
||||||
OS_16,OS_S16:
|
OS_16,OS_S16:
|
||||||
s3 := S_WL;
|
s3 := S_WL;
|
||||||
OS_32,OS_S32:
|
OS_32,OS_S32:
|
||||||
s3 := S_L;
|
s3 := S_L;
|
||||||
else
|
else
|
||||||
internalerror(200109223);
|
internalerror(200109223);
|
||||||
end;
|
end;
|
||||||
else internalerror(200109227);
|
else internalerror(200109227);
|
||||||
end;
|
end;
|
||||||
if s3 in [S_B,S_W,S_L]
|
if s3 in [S_B,S_W,S_L]
|
||||||
then
|
then
|
||||||
op := A_LD
|
op := A_LD
|
||||||
{ else if s3=S_DW
|
{ else if s3=S_DW
|
||||||
then
|
then
|
||||||
op:=A_LDD
|
op:=A_LDD
|
||||||
else if s3 in [OS_8,OS_16,OS_32]
|
else if s3 in [OS_8,OS_16,OS_32]
|
||||||
then
|
then
|
||||||
op := A_NONE}
|
op := A_NONE}
|
||||||
else
|
else
|
||||||
op := A_NONE;
|
op := A_NONE;
|
||||||
end;
|
end;
|
||||||
procedure tcgSPARC.floatloadops(t:tcgsize;VAR op:tasmop;VAR s:topsize);
|
procedure tcgSPARC.floatloadops(t:tcgsize;VAR op:tasmop;VAR s:topsize);
|
||||||
BEGIN
|
BEGIN
|
||||||
(* case t of
|
(* case t of
|
||||||
@ -1257,7 +1256,10 @@ BEGIN
|
|||||||
END.
|
END.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.12 2002-10-08 17:17:03 mazen
|
Revision 1.13 2002-10-10 15:10:39 mazen
|
||||||
|
* Internal error fixed, but usually i386 parameter model used
|
||||||
|
|
||||||
|
Revision 1.12 2002/10/08 17:17:03 mazen
|
||||||
*** empty log message ***
|
*** empty log message ***
|
||||||
|
|
||||||
Revision 1.11 2002/10/07 20:33:04 mazen
|
Revision 1.11 2002/10/07 20:33:04 mazen
|
||||||
|
@ -1,319 +1,305 @@
|
|||||||
{*****************************************************************************}
|
{******************************************************************************
|
||||||
{ File : cpupara.pas }
|
$Id$
|
||||||
{ Author : Mazen NEIFER }
|
Copyright (c) 2002 by Florian Klaempfl
|
||||||
{ Project : Free Pascal Compiler (FPC) }
|
|
||||||
{ Creation date : 2002\07\13 }
|
|
||||||
{ Last modification date : 2002\08\20 }
|
|
||||||
{ Licence : GPL }
|
|
||||||
{ Bug report : mazen.neifer.01@supaero.org }
|
|
||||||
{*****************************************************************************}
|
|
||||||
{
|
|
||||||
$Id$
|
|
||||||
Copyright (c) 2002 by Florian Klaempfl
|
|
||||||
|
|
||||||
PowerPC specific calling conventions
|
PowerPC specific calling conventions
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
unit cpupara;
|
unit cpupara;
|
||||||
{SPARC specific calling conventions are handled by this unit}
|
{SPARC specific calling conventions are handled by this unit}
|
||||||
{$INCLUDE fpcdefs.inc}
|
{$INCLUDE fpcdefs.inc}
|
||||||
interface
|
interface
|
||||||
uses
|
uses
|
||||||
cpubase,
|
cpubase,
|
||||||
symconst,symbase,symtype,symdef,paramgr;
|
symconst,symbase,symtype,symdef,paramgr;
|
||||||
type
|
type
|
||||||
TSparcParaManager=class(TParaManager)
|
TSparcParaManager=class(TParaManager)
|
||||||
function GetIntParaLoc(nr:longint):TParaLocation;override;
|
function GetIntParaLoc(nr:longint):TParaLocation;override;
|
||||||
procedure create_param_loc_info(p:TAbstractProcDef);override;
|
procedure create_param_loc_info(p:TAbstractProcDef);override;
|
||||||
function GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;override;
|
function GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;override;
|
||||||
end;
|
end;
|
||||||
implementation
|
implementation
|
||||||
uses
|
uses
|
||||||
verbose,
|
verbose,
|
||||||
globtype,
|
globtype,
|
||||||
cpuinfo,cginfo,cgbase,
|
cpuinfo,cginfo,cgbase,
|
||||||
defbase;
|
defbase;
|
||||||
function TSparcParaManager.GetIntParaLoc(nr:longint):TParaLocation;
|
function TSparcParaManager.GetIntParaLoc(nr:longint):TParaLocation;
|
||||||
begin
|
begin
|
||||||
if nr<1
|
if nr<1
|
||||||
then
|
then
|
||||||
InternalError(2002100806);
|
InternalError(2002100806);
|
||||||
FillChar(Result,SizeOf(TParaLocation),0);
|
FillChar(Result,SizeOf(TParaLocation),0);
|
||||||
Dec(nr);
|
Dec(nr);
|
||||||
with Result do
|
with Result do
|
||||||
if nr<6
|
if nr<6
|
||||||
then{The six first parameters are passed into registers}
|
then{The six first parameters are passed into registers}
|
||||||
begin
|
begin
|
||||||
loc:=LOC_REGISTER;
|
loc:=LOC_REGISTER;
|
||||||
register:=TRegister(LongInt(R_O0)+nr);
|
register:=TRegister(LongInt(R_O0)+nr);
|
||||||
WriteLn('-------------------------------------------');
|
WriteLn('-------------------------------------------');
|
||||||
end
|
end
|
||||||
else{The other parameters are passed into the frame}
|
else{The other parameters are passed into the frame}
|
||||||
begin
|
begin
|
||||||
loc:=LOC_REFERENCE;
|
loc:=LOC_REFERENCE;
|
||||||
reference.index:=frame_pointer_reg;
|
reference.index:=frame_pointer_reg;
|
||||||
reference.offset:=-92-(nr-6)*4;
|
reference.offset:=-92-(nr-6)*4;
|
||||||
WriteLn('+++++++++++++++++++++++++++++++++++++++++++');
|
WriteLn('+++++++++++++++++++++++++++++++++++++++++++');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
function GetParaLoc(p:TDef):TLoc;
|
function GetParaLoc(p:TDef):TLoc;
|
||||||
begin
|
begin
|
||||||
{Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER if
|
{Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER if
|
||||||
push_addr_param for the def is true}
|
push_addr_param for the def is true}
|
||||||
case p.DefType of
|
case p.DefType of
|
||||||
OrdDef:
|
OrdDef:
|
||||||
GetParaLoc:=LOC_REGISTER;
|
GetParaLoc:=LOC_REGISTER;
|
||||||
FloatDef:
|
FloatDef:
|
||||||
GetParaLoc:=LOC_FPUREGISTER;
|
GetParaLoc:=LOC_FPUREGISTER;
|
||||||
enumdef:
|
enumdef:
|
||||||
getparaloc:=LOC_REGISTER;
|
getparaloc:=LOC_REGISTER;
|
||||||
pointerdef:
|
pointerdef:
|
||||||
getparaloc:=LOC_REGISTER;
|
getparaloc:=LOC_REGISTER;
|
||||||
formaldef:
|
formaldef:
|
||||||
getparaloc:=LOC_REGISTER;
|
getparaloc:=LOC_REGISTER;
|
||||||
classrefdef:
|
classrefdef:
|
||||||
getparaloc:=LOC_REGISTER;
|
getparaloc:=LOC_REGISTER;
|
||||||
recorddef:
|
recorddef:
|
||||||
getparaloc:=LOC_REFERENCE;
|
getparaloc:=LOC_REFERENCE;
|
||||||
objectdef:
|
objectdef:
|
||||||
if is_object(p) then
|
if is_object(p)
|
||||||
getparaloc:=LOC_REFERENCE
|
then
|
||||||
else
|
getparaloc:=LOC_REFERENCE
|
||||||
getparaloc:=LOC_REGISTER;
|
else
|
||||||
stringdef:
|
getparaloc:=LOC_REGISTER;
|
||||||
if is_shortstring(p) or is_longstring(p) then
|
stringdef:
|
||||||
getparaloc:=LOC_REFERENCE
|
if is_shortstring(p) or is_longstring(p)
|
||||||
else
|
then
|
||||||
getparaloc:=LOC_REGISTER;
|
getparaloc:=LOC_REFERENCE
|
||||||
procvardef:
|
else
|
||||||
if (po_methodpointer in tprocvardef(p).procoptions) then
|
getparaloc:=LOC_REGISTER;
|
||||||
getparaloc:=LOC_REFERENCE
|
procvardef:
|
||||||
else
|
if (po_methodpointer in tprocvardef(p).procoptions)
|
||||||
getparaloc:=LOC_REGISTER;
|
then
|
||||||
filedef:
|
getparaloc:=LOC_REFERENCE
|
||||||
getparaloc:=LOC_REGISTER;
|
else
|
||||||
arraydef:
|
getparaloc:=LOC_REGISTER;
|
||||||
getparaloc:=LOC_REFERENCE;
|
filedef:
|
||||||
setdef:
|
getparaloc:=LOC_REGISTER;
|
||||||
if is_smallset(p) then
|
arraydef:
|
||||||
getparaloc:=LOC_REGISTER
|
getparaloc:=LOC_REFERENCE;
|
||||||
else
|
setdef:
|
||||||
getparaloc:=LOC_REFERENCE;
|
if is_smallset(p)
|
||||||
variantdef:
|
then
|
||||||
getparaloc:=LOC_REFERENCE;
|
getparaloc:=LOC_REGISTER
|
||||||
{ avoid problems with errornous definitions }
|
else
|
||||||
errordef:
|
getparaloc:=LOC_REFERENCE;
|
||||||
getparaloc:=LOC_REGISTER;
|
variantdef:
|
||||||
else
|
getparaloc:=LOC_REFERENCE;
|
||||||
internalerror(2002071001);
|
{ avoid problems with errornous definitions }
|
||||||
end;
|
errordef:
|
||||||
end;
|
getparaloc:=LOC_REGISTER;
|
||||||
|
else
|
||||||
|
internalerror(2002071001);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
procedure TSparcParaManager.create_param_loc_info(p:tabstractprocdef);
|
procedure TSparcParaManager.create_param_loc_info(p:tabstractprocdef);
|
||||||
var
|
var
|
||||||
nextintreg,nextfloatreg,nextmmreg : tregister;
|
nextintreg,nextfloatreg:tregister;
|
||||||
stack_offset : aword;
|
stack_offset : aword;
|
||||||
hp : tparaitem;
|
hp : tparaitem;
|
||||||
loc : tloc;
|
loc : tloc;
|
||||||
is_64bit: boolean;
|
is_64bit: boolean;
|
||||||
begin
|
begin
|
||||||
nextintreg:=R_O0;
|
nextintreg:=R_O0;
|
||||||
nextfloatreg:=R_F0;
|
nextfloatreg:=R_F0;
|
||||||
nextmmreg:=R_NONE;
|
stack_offset:=92;
|
||||||
stack_offset:=92;
|
|
||||||
{pointer for structured results ?}
|
|
||||||
if not is_void(p.RetType.def)
|
|
||||||
then
|
|
||||||
if not(ret_in_reg(p.rettype.def))
|
|
||||||
then
|
|
||||||
inc(nextintreg);
|
|
||||||
{frame pointer for nested procedures?}
|
|
||||||
{ inc(nextintreg); }
|
|
||||||
{ constructor? }
|
|
||||||
{ destructor? }
|
|
||||||
WriteLn('***********************************************');
|
WriteLn('***********************************************');
|
||||||
hp:=TParaItem(p.para.last);
|
hp:=TParaItem(p.para.First);
|
||||||
while assigned(hp) do
|
while assigned(hp) do
|
||||||
begin
|
begin
|
||||||
loc:=GetParaLoc(hp.paratype.def);
|
loc:=GetParaLoc(hp.paratype.def);
|
||||||
hp.paraloc.sp_fixup:=0;
|
case loc of
|
||||||
case loc of
|
LOC_REGISTER:
|
||||||
LOC_REGISTER:
|
begin
|
||||||
begin
|
hp.paraloc.size:=def_cgSize(hp.paratype.def);
|
||||||
hp.paraloc.size:=def_cgSize(hp.paratype.def);
|
if hp.paraloc.size=OS_NO
|
||||||
if hp.paraloc.size=OS_NO
|
then
|
||||||
then
|
hp.paraloc.size:=OS_ADDR;
|
||||||
hp.paraloc.size:=OS_ADDR;
|
is_64bit:=hp.paraloc.size in [OS_64,OS_S64];
|
||||||
is_64bit:=hp.paraloc.size in [OS_64,OS_S64];
|
if NextIntReg<=TRegister(ord(R_O5)-ord(is_64bit))
|
||||||
if NextIntReg<=TRegister(ord(R_O5)-ord(is_64bit))
|
then
|
||||||
then
|
begin
|
||||||
begin
|
WriteLn('Allocating ',std_reg2str[NextIntReg]);
|
||||||
WriteLn('Allocating ',std_reg2str[NextIntReg]);
|
hp.paraloc.loc:=LOC_REGISTER;
|
||||||
hp.paraloc.loc:=LOC_REGISTER;
|
hp.paraloc.registerlow:=NextIntReg;
|
||||||
hp.paraloc.registerlow:=NextIntReg;
|
inc(NextIntReg);
|
||||||
inc(NextIntReg);
|
if is_64bit
|
||||||
if is_64bit
|
then
|
||||||
then
|
begin
|
||||||
begin
|
hp.paraloc.registerhigh:=nextintreg;
|
||||||
hp.paraloc.registerhigh:=nextintreg;
|
inc(nextintreg);
|
||||||
inc(nextintreg);
|
end;
|
||||||
end;
|
end
|
||||||
end
|
else
|
||||||
else
|
begin
|
||||||
begin
|
nextintreg:=R_O6;
|
||||||
nextintreg:=R_O6;
|
hp.paraloc.loc:=LOC_REFERENCE;
|
||||||
hp.paraloc.loc:=LOC_REFERENCE;
|
hp.paraloc.reference.index:=stack_pointer_reg;
|
||||||
hp.paraloc.reference.index:=stack_pointer_reg;
|
hp.paraloc.reference.offset:=stack_offset;
|
||||||
hp.paraloc.reference.offset:=stack_offset;
|
if not is_64bit
|
||||||
if not is_64bit
|
then
|
||||||
then
|
inc(stack_offset,4)
|
||||||
inc(stack_offset,4)
|
else
|
||||||
else
|
inc(stack_offset,8);
|
||||||
inc(stack_offset,8);
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
LOC_FPUREGISTER:
|
||||||
LOC_FPUREGISTER:
|
begin
|
||||||
begin
|
if hp.paratyp in [vs_var,vs_out] then
|
||||||
if hp.paratyp in [vs_var,vs_out] then
|
begin
|
||||||
begin
|
if nextintreg<=R_O5 then
|
||||||
if nextintreg<=R_O5 then
|
begin
|
||||||
begin
|
hp.paraloc.size:=OS_ADDR;
|
||||||
hp.paraloc.size:=OS_ADDR;
|
hp.paraloc.loc:=LOC_REGISTER;
|
||||||
hp.paraloc.loc:=LOC_REGISTER;
|
hp.paraloc.register:=nextintreg;
|
||||||
hp.paraloc.register:=nextintreg;
|
inc(nextintreg);
|
||||||
inc(nextintreg);
|
end
|
||||||
end
|
else
|
||||||
else
|
begin
|
||||||
begin
|
{!!!!!!!}
|
||||||
{!!!!!!!}
|
hp.paraloc.size:=def_cgsize(hp.paratype.def);
|
||||||
hp.paraloc.size:=def_cgsize(hp.paratype.def);
|
internalerror(2002071006);
|
||||||
internalerror(2002071006);
|
end;
|
||||||
end;
|
end
|
||||||
end
|
else if nextfloatreg<=R_F10 then
|
||||||
else if nextfloatreg<=R_F10 then
|
begin
|
||||||
begin
|
hp.paraloc.size:=def_cgsize(hp.paratype.def);
|
||||||
hp.paraloc.size:=def_cgsize(hp.paratype.def);
|
hp.paraloc.loc:=LOC_FPUREGISTER;
|
||||||
hp.paraloc.loc:=LOC_FPUREGISTER;
|
hp.paraloc.register:=nextfloatreg;
|
||||||
hp.paraloc.register:=nextfloatreg;
|
inc(nextfloatreg);
|
||||||
inc(nextfloatreg);
|
end
|
||||||
end
|
else
|
||||||
else
|
begin
|
||||||
begin
|
{!!!!!!!}
|
||||||
{!!!!!!!}
|
hp.paraloc.size:=def_cgsize(hp.paratype.def);
|
||||||
hp.paraloc.size:=def_cgsize(hp.paratype.def);
|
internalerror(2002071004);
|
||||||
internalerror(2002071004);
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
LOC_REFERENCE:
|
||||||
LOC_REFERENCE:
|
begin
|
||||||
begin
|
hp.paraloc.size:=OS_ADDR;
|
||||||
hp.paraloc.size:=OS_ADDR;
|
if push_addr_param(hp.paratype.def,p.proccalloption in [pocall_cdecl,pocall_cppdecl]) or (hp.paratyp in [vs_var,vs_out]) then
|
||||||
if push_addr_param(hp.paratype.def,p.proccalloption in [pocall_cdecl,pocall_cppdecl]) or (hp.paratyp in [vs_var,vs_out]) then
|
begin
|
||||||
begin
|
if nextintreg<=R_O5 then
|
||||||
if nextintreg<=R_O5 then
|
begin
|
||||||
begin
|
hp.paraloc.loc:=LOC_REGISTER;
|
||||||
hp.paraloc.loc:=LOC_REGISTER;
|
hp.paraloc.register:=nextintreg;
|
||||||
hp.paraloc.register:=nextintreg;
|
inc(nextintreg);
|
||||||
inc(nextintreg);
|
end
|
||||||
end
|
else
|
||||||
else
|
begin
|
||||||
begin
|
hp.paraloc.loc:=LOC_REFERENCE;
|
||||||
hp.paraloc.loc:=LOC_REFERENCE;
|
hp.paraloc.reference.index:=stack_pointer_reg;
|
||||||
hp.paraloc.reference.index:=stack_pointer_reg;
|
hp.paraloc.reference.offset:=stack_offset;
|
||||||
hp.paraloc.reference.offset:=stack_offset;
|
inc(stack_offset,4);
|
||||||
inc(stack_offset,4);
|
end;
|
||||||
end;
|
end
|
||||||
end
|
else
|
||||||
else
|
begin
|
||||||
begin
|
hp.paraloc.loc:=LOC_REFERENCE;
|
||||||
hp.paraloc.loc:=LOC_REFERENCE;
|
hp.paraloc.reference.index:=stack_pointer_reg;
|
||||||
hp.paraloc.reference.index:=stack_pointer_reg;
|
hp.paraloc.reference.offset:=stack_offset;
|
||||||
hp.paraloc.reference.offset:=stack_offset;
|
inc(stack_offset,hp.paratype.def.size);
|
||||||
inc(stack_offset,hp.paratype.def.size);
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
else
|
||||||
else
|
internalerror(2002071002);
|
||||||
internalerror(2002071002);
|
end;
|
||||||
end;
|
hp:=TParaItem(hp.Next);
|
||||||
hp:=TParaItem(hp.previous);
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
|
function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
|
||||||
begin
|
begin
|
||||||
case p.rettype.def.deftype of
|
case p.rettype.def.deftype of
|
||||||
orddef,enumdef:
|
orddef,enumdef:
|
||||||
begin
|
begin
|
||||||
WriteLn('Allocating i0 as return register');
|
WriteLn('Allocating i0 as return register');
|
||||||
GetFuncRetParaLoc.loc:=LOC_REGISTER;
|
GetFuncRetParaLoc.loc:=LOC_REGISTER;
|
||||||
GetFuncRetParaLoc.register:=R_i0;
|
GetFuncRetParaLoc.register:=R_i0;
|
||||||
GetFuncRetParaLoc.size:=def_cgsize(p.rettype.def);
|
GetFuncRetParaLoc.size:=def_cgsize(p.rettype.def);
|
||||||
if GetFuncRetParaLoc.size in [OS_S64,OS_64]
|
if GetFuncRetParaLoc.size in [OS_S64,OS_64]
|
||||||
then
|
then
|
||||||
GetFuncRetParaLoc.RegisterHigh:=R_O1;
|
GetFuncRetParaLoc.RegisterHigh:=R_O1;
|
||||||
end;
|
end;
|
||||||
floatdef:
|
floatdef:
|
||||||
begin
|
begin
|
||||||
GetFuncRetParaLoc.loc:=LOC_FPUREGISTER;
|
GetFuncRetParaLoc.loc:=LOC_FPUREGISTER;
|
||||||
GetFuncRetParaLoc.register:=R_F1;
|
GetFuncRetParaLoc.register:=R_F1;
|
||||||
GetFuncRetParaLoc.size:=def_cgsize(p.rettype.def);
|
GetFuncRetParaLoc.size:=def_cgsize(p.rettype.def);
|
||||||
end;
|
end;
|
||||||
{ smallsets are OS_INT in R3, others are OS_ADDR in R3 -> the same }
|
{ smallsets are OS_INT in R3, others are OS_ADDR in R3 -> the same }
|
||||||
{ ugly, I know :) (JM) }
|
{ ugly, I know :) (JM) }
|
||||||
setdef,
|
setdef,
|
||||||
variantdef,
|
variantdef,
|
||||||
pointerdef,
|
pointerdef,
|
||||||
formaldef,
|
formaldef,
|
||||||
classrefdef,
|
classrefdef,
|
||||||
recorddef,
|
recorddef,
|
||||||
objectdef,
|
objectdef,
|
||||||
stringdef,
|
stringdef,
|
||||||
procvardef,
|
procvardef,
|
||||||
filedef,
|
filedef,
|
||||||
arraydef,
|
arraydef,
|
||||||
errordef:
|
errordef:
|
||||||
begin
|
begin
|
||||||
GetFuncRetParaLoc.loc:=LOC_REGISTER;
|
GetFuncRetParaLoc.loc:=LOC_REGISTER;
|
||||||
GetFuncRetParaLoc.register:=R_O0;
|
GetFuncRetParaLoc.register:=R_O0;
|
||||||
GetFuncRetParaLoc.size:=OS_ADDR;
|
GetFuncRetParaLoc.size:=OS_ADDR;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(2002090903);
|
internalerror(2002090903);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
begin
|
begin
|
||||||
ParaManager:=TSparcParaManager.create;
|
ParaManager:=TSparcParaManager.create;
|
||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.5 2002-10-09 13:52:19 mazen
|
Revision 1.6 2002-10-10 15:10:39 mazen
|
||||||
just incase some one wolud help me debugging that\!
|
* Internal error fixed, but usually i386 parameter model used
|
||||||
|
|
||||||
Revision 1.4 2002/10/08 21:02:22 mazen
|
Revision 1.5 2002/10/09 13:52:19 mazen
|
||||||
* debugging register allocation
|
just incase some one wolud help me debugging that\!
|
||||||
|
|
||||||
Revision 1.3 2002/10/07 20:33:05 mazen
|
Revision 1.4 2002/10/08 21:02:22 mazen
|
||||||
word alignement modified in g_stack_frame
|
* debugging register allocation
|
||||||
|
|
||||||
|
Revision 1.3 2002/10/07 20:33:05 mazen
|
||||||
|
word alignement modified in g_stack_frame
|
||||||
|
|
||||||
Revision 1.2 2002/10/04 21:57:42 mazen
|
Revision 1.2 2002/10/04 21:57:42 mazen
|
||||||
* register allocation for parameters now done in cpupara, but InternalError(200109223) in cgcpu.pas:1053 is still not fixed du to location_force problem in ncgutils.pas:419
|
* register allocation for parameters now done in cpupara, but InternalError(200109223) in cgcpu.pas:1053 is still not fixed du to location_force problem in ncgutils.pas:419
|
||||||
|
|
||||||
Revision 1.1 2002/08/21 13:30:07 mazen
|
Revision 1.1 2002/08/21 13:30:07 mazen
|
||||||
*** empty log message ***
|
*** empty log message ***
|
||||||
|
|
||||||
Revision 1.2 2002/07/11 14:41:34 florian
|
Revision 1.2 2002/07/11 14:41:34 florian
|
||||||
* start of the new generic parameter handling
|
* start of the new generic parameter handling
|
||||||
|
|
||||||
Revision 1.1 2002/07/07 09:44:32 florian
|
Revision 1.1 2002/07/07 09:44:32 florian
|
||||||
* powerpc target fixed, very simple units can be compiled
|
* powerpc target fixed, very simple units can be compiled
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{*****************************************************************************
|
||||||
$Id$
|
$Id$
|
||||||
Copyright (c) 2002 by Florian Klaempfl
|
Copyright (c) 2002 by Florian Klaempfl
|
||||||
|
|
||||||
@ -18,78 +18,66 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
****************************************************************************
|
****************************************************************************}
|
||||||
}
|
|
||||||
|
|
||||||
{ This unit contains the CPU specific part of tprocinfo. }
|
{ This unit contains the CPU specific part of tprocinfo. }
|
||||||
unit cpupi;
|
unit cpupi;
|
||||||
|
{$INCLUDE fpcdefs.inc}
|
||||||
{$i fpcdefs.inc}
|
interface
|
||||||
|
uses
|
||||||
interface
|
cutils,
|
||||||
|
cgbase,cpuinfo;
|
||||||
uses
|
type
|
||||||
cutils,
|
TSparcprocinfo=class(TProcInfo)
|
||||||
cgbase,cpuinfo;
|
{overall size of allocated stack space, currently this is used for the PowerPC only}
|
||||||
|
localsize:aword;
|
||||||
type
|
{max. of space need for parameters, currently used by the PowerPC port only}
|
||||||
TSparcprocinfo = class(tprocinfo)
|
maxpushedparasize:aword;
|
||||||
{ overall size of allocated stack space, currently this is used for the PowerPC only }
|
constructor create;override;
|
||||||
localsize : aword;
|
procedure after_header;override;
|
||||||
|
procedure after_pass1;override;
|
||||||
{ max. of space need for parameters, currently used by the PowerPC port only }
|
end;
|
||||||
maxpushedparasize : aword;
|
implementation
|
||||||
|
uses
|
||||||
constructor create;override;
|
globtype,globals,
|
||||||
procedure after_header;override;
|
aasmtai,
|
||||||
procedure after_pass1;override;
|
tgobj;
|
||||||
end;
|
constructor TSparcprocinfo.create;
|
||||||
|
begin
|
||||||
|
inherited create;
|
||||||
implementation
|
maxpushedparasize:=0;
|
||||||
|
localsize:=0;
|
||||||
uses
|
end;
|
||||||
globtype,globals,
|
procedure TSparcprocinfo.after_header;
|
||||||
aasmtai,
|
begin
|
||||||
tgobj;
|
{ this value is necessary for nested procedures }
|
||||||
|
procdef.localst.address_fixup:=align(procdef.parast.datasize,16);
|
||||||
constructor TSparcprocinfo.create;
|
end;
|
||||||
|
procedure TSparcprocinfo.after_pass1;
|
||||||
begin
|
begin
|
||||||
inherited create;
|
procdef.parast.address_fixup:=align(maxpushedparasize,16);
|
||||||
maxpushedparasize:=0;
|
if cs_asm_source in aktglobalswitches
|
||||||
localsize:=0;
|
then
|
||||||
end;
|
aktproccode.insert(Tai_comment.Create(strpnew('Parameter copies start at: %i6+'+tostr(procdef.parast.address_fixup))));
|
||||||
|
procdef.localst.address_fixup:=align(procdef.parast.address_fixup+procdef.parast.datasize,16);
|
||||||
procedure TSparcprocinfo.after_header;
|
if cs_asm_source in aktglobalswitches
|
||||||
begin
|
then
|
||||||
{ this value is necessary for nested procedures }
|
aktproccode.insert(Tai_comment.Create(strpnew('Locals start at: %o6+'+tostr(procdef.localst.address_fixup))));
|
||||||
procdef.localst.address_fixup:=align(procdef.parast.datasize,16);
|
procinfo.firsttemp_offset:=align(procdef.localst.address_fixup+procdef.localst.datasize,16);
|
||||||
end;
|
if cs_asm_source in aktglobalswitches
|
||||||
|
then
|
||||||
procedure TSparcprocinfo.after_pass1;
|
aktproccode.insert(Tai_comment.Create(strpnew('Temp. space start: %o6+'+tostr(procinfo.firsttemp_offset))));
|
||||||
begin
|
tg.firsttemp:=procinfo.firsttemp_offset;
|
||||||
procdef.parast.address_fixup:=align(maxpushedparasize,16);
|
tg.lasttemp:=procinfo.firsttemp_offset;
|
||||||
if cs_asm_source in aktglobalswitches then
|
end;
|
||||||
aktproccode.insert(Tai_comment.Create(strpnew('Parameter copies start at: r1+'+tostr(procdef.parast.address_fixup))));
|
|
||||||
procdef.localst.address_fixup:=align(procdef.parast.address_fixup+procdef.parast.datasize,16);
|
|
||||||
if cs_asm_source in aktglobalswitches then
|
|
||||||
aktproccode.insert(Tai_comment.Create(strpnew('Locals start at: r1+'+tostr(procdef.localst.address_fixup))));
|
|
||||||
procinfo.firsttemp_offset:=align(procdef.localst.address_fixup+procdef.localst.datasize,16);
|
|
||||||
if cs_asm_source in aktglobalswitches then
|
|
||||||
aktproccode.insert(Tai_comment.Create(strpnew('Temp. space start: r1+'+tostr(procinfo.firsttemp_offset))));
|
|
||||||
|
|
||||||
//!!!! tg.setfirsttemp(procinfo.firsttemp_offset);
|
|
||||||
tg.firsttemp:=procinfo.firsttemp_offset;
|
|
||||||
tg.lasttemp:=procinfo.firsttemp_offset;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cprocinfo:=TSparcprocinfo;
|
cprocinfo:=TSparcprocinfo;
|
||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.2 2002-08-29 11:02:36 mazen
|
Revision 1.3 2002-10-10 15:10:39 mazen
|
||||||
|
* Internal error fixed, but usually i386 parameter model used
|
||||||
|
|
||||||
|
Revision 1.2 2002/08/29 11:02:36 mazen
|
||||||
added support for SPARC processors
|
added support for SPARC processors
|
||||||
|
|
||||||
Revision 1.1 2002/08/23 10:08:28 mazen
|
Revision 1.1 2002/08/23 10:08:28 mazen
|
||||||
@ -104,5 +92,3 @@ end.
|
|||||||
Revision 1.1 2002/08/17 09:23:49 florian
|
Revision 1.1 2002/08/17 09:23:49 florian
|
||||||
* first part of procinfo rewrite
|
* first part of procinfo rewrite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user