mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 21:09:07 +02:00
* macos stack frame size computing updated
+ macos epilogue: control register now restored * macos prologue and epilogue: fp reg now saved and restored
This commit is contained in:
parent
1dfea79867
commit
4d3ed1a22c
@ -1110,6 +1110,42 @@ const
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
macosLinkageAreaSize = 24;
|
||||||
|
registerSaveAreaMaxSize = 19*4 + 18*8;
|
||||||
|
|
||||||
|
procedure save_fp_regs(list : taasmoutput);
|
||||||
|
|
||||||
|
var regcounter: TRegister;
|
||||||
|
href : treference;
|
||||||
|
offset: integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
offset:= 0;
|
||||||
|
for regcounter := R_F14 to R_F31 do
|
||||||
|
begin
|
||||||
|
offset:= offset - 8;
|
||||||
|
reference_reset_base(href, STACK_POINTER_REG, offset);
|
||||||
|
list.concat(taicpu.op_reg_ref(A_STFD, regcounter, href));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure restore_fp_regs(list : taasmoutput);
|
||||||
|
|
||||||
|
var regcounter: TRegister;
|
||||||
|
href : treference;
|
||||||
|
offset: integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
offset:= 0;
|
||||||
|
for regcounter := R_F14 to R_F31 do
|
||||||
|
begin
|
||||||
|
offset:= offset - 8;
|
||||||
|
reference_reset_base(href, STACK_POINTER_REG, offset);
|
||||||
|
list.concat(taicpu.op_reg_ref(A_LFD, regcounter, href));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure tcgppc.g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
|
procedure tcgppc.g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
|
||||||
{ generated the entry code of a procedure/function. Note: localsize is the }
|
{ generated the entry code of a procedure/function. Note: localsize is the }
|
||||||
{ sum of the size necessary for local variables and the maximum possible }
|
{ sum of the size necessary for local variables and the maximum possible }
|
||||||
@ -1129,28 +1165,36 @@ const
|
|||||||
{ allocate registers containing reg parameters }
|
{ allocate registers containing reg parameters }
|
||||||
for regcounter := R_3 to R_10 do
|
for regcounter := R_3 to R_10 do
|
||||||
a_reg_alloc(list,regcounter);
|
a_reg_alloc(list,regcounter);
|
||||||
|
|
||||||
{ save return address... }
|
{ save return address... }
|
||||||
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
|
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
|
||||||
{ ... in caller's frame }
|
{ ... in caller's frame }
|
||||||
reference_reset_base(href,STACK_POINTER_REG,8);
|
reference_reset_base(href,STACK_POINTER_REG,8);
|
||||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
||||||
a_reg_dealloc(list,R_0);
|
a_reg_dealloc(list,R_0);
|
||||||
|
|
||||||
{ save floating-point registers }
|
{ save floating-point registers }
|
||||||
{ !!! has to be optimized: only save registers that are used }
|
{ !!! has to be optimized: only save registers that are used }
|
||||||
a_call_name(list,'_savef14');
|
save_fp_regs(list);
|
||||||
|
(* a_call_name(list,'_savef14'); *)
|
||||||
{ save gprs in gpr save area }
|
{ save gprs in gpr save area }
|
||||||
{ !!! has to be optimized: only save registers that are used }
|
{ !!! has to be optimized: only save registers that are used }
|
||||||
reference_reset_base(href,STACK_POINTER_REG,-220);
|
reference_reset_base(href,STACK_POINTER_REG,-220);
|
||||||
list.concat(taicpu.op_reg_ref(A_STMW,R_13,href));
|
list.concat(taicpu.op_reg_ref(A_STMW,R_13,href));
|
||||||
|
|
||||||
{ save the CR if necessary ( !!! always done currently ) }
|
{ save the CR if necessary ( !!! always done currently ) }
|
||||||
a_reg_alloc(list,R_0);
|
a_reg_alloc(list,R_0);
|
||||||
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_CR));
|
list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_CR));
|
||||||
reference_reset_base(href,stack_pointer_reg,LA_CR);
|
reference_reset_base(href,stack_pointer_reg,LA_CR);
|
||||||
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
list.concat(taicpu.op_reg_ref(A_STW,R_0,href));
|
||||||
a_reg_dealloc(list,R_0);
|
a_reg_dealloc(list,R_0);
|
||||||
|
|
||||||
{ save pointer to incoming arguments }
|
{ save pointer to incoming arguments }
|
||||||
list.concat(taicpu.op_reg_reg_const(A_ORI,R_31,STACK_POINTER_REG,0));
|
list.concat(taicpu.op_reg_reg_const(A_ORI,R_31,STACK_POINTER_REG,0));
|
||||||
|
|
||||||
|
(*
|
||||||
a_reg_alloc(list,R_12);
|
a_reg_alloc(list,R_12);
|
||||||
|
|
||||||
{ 0 or 8 based on SP alignment }
|
{ 0 or 8 based on SP alignment }
|
||||||
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
||||||
R_12,STACK_POINTER_REG,0,28,28));
|
R_12,STACK_POINTER_REG,0,28,28));
|
||||||
@ -1159,7 +1203,16 @@ const
|
|||||||
-localsize));
|
-localsize));
|
||||||
{ establish new alignment }
|
{ establish new alignment }
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_STWUX,STACK_POINTER_REG,STACK_POINTER_REG,R_12));
|
list.concat(taicpu.op_reg_reg_reg(A_STWUX,STACK_POINTER_REG,STACK_POINTER_REG,R_12));
|
||||||
|
|
||||||
a_reg_dealloc(list,R_12);
|
a_reg_dealloc(list,R_12);
|
||||||
|
*)
|
||||||
|
|
||||||
|
{ allocate stack frame }
|
||||||
|
localsize:= align(localsize + macosLinkageAreaSize + registerSaveAreaMaxSize, 16);
|
||||||
|
reference_reset_base(href,R_1,-localsize);
|
||||||
|
a_load_store(list,A_STWU,R_1,href);
|
||||||
|
|
||||||
|
|
||||||
{ now comes the AltiVec context save, not yet implemented !!! }
|
{ now comes the AltiVec context save, not yet implemented !!! }
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1176,14 +1229,31 @@ const
|
|||||||
|
|
||||||
{ restore SP }
|
{ restore SP }
|
||||||
list.concat(taicpu.op_reg_reg_const(A_ORI,STACK_POINTER_REG,R_31,0));
|
list.concat(taicpu.op_reg_reg_const(A_ORI,STACK_POINTER_REG,R_31,0));
|
||||||
|
|
||||||
|
{ restore the CR if necessary ( !!! always done currently ) }
|
||||||
|
a_reg_alloc(list,R_0);
|
||||||
|
list.concat(taicpu.op_reg_reg(A_MTSPR,R_0,R_CR));
|
||||||
|
reference_reset_base(href,stack_pointer_reg,LA_CR);
|
||||||
|
list.concat(taicpu.op_reg_ref(A_LWZ,R_0,href));
|
||||||
|
a_reg_dealloc(list,R_0);
|
||||||
{ restore gprs }
|
{ restore gprs }
|
||||||
reference_reset_base(href,STACK_POINTER_REG,-220);
|
reference_reset_base(href,STACK_POINTER_REG,-220);
|
||||||
list.concat(taicpu.op_reg_ref(A_LMW,R_13,href));
|
list.concat(taicpu.op_reg_ref(A_LMW,R_13,href));
|
||||||
{ restore return address ... }
|
{ restore return address ... }
|
||||||
reference_reset_base(href,STACK_POINTER_REG,8);
|
reference_reset_base(href,STACK_POINTER_REG,8);
|
||||||
list.concat(taicpu.op_reg_ref(A_LWZ,R_0,href));
|
list.concat(taicpu.op_reg_ref(A_LWZ,R_0,href));
|
||||||
|
|
||||||
|
(*
|
||||||
{ ... and return from _restf14 }
|
{ ... and return from _restf14 }
|
||||||
list.concat(taicpu.op_sym_ofs(A_B,objectlibrary.newasmsymbol('_restf14'),0));
|
list.concat(taicpu.op_sym_ofs(A_B,objectlibrary.newasmsymbol('_restf14'),0));
|
||||||
|
*)
|
||||||
|
|
||||||
|
{ restore fp registers }
|
||||||
|
restore_fp_regs(list);
|
||||||
|
|
||||||
|
{ return to caller }
|
||||||
|
list.concat(taicpu.op_reg_reg(A_MTSPR,R_0,R_LR));
|
||||||
|
list.concat(taicpu.op_none(A_BLR));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1700,7 +1770,12 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.61 2002-10-19 12:50:36 olle
|
Revision 1.62 2002-10-19 23:51:48 olle
|
||||||
|
* macos stack frame size computing updated
|
||||||
|
+ macos epilogue: control register now restored
|
||||||
|
* macos prologue and epilogue: fp reg now saved and restored
|
||||||
|
|
||||||
|
Revision 1.61 2002/10/19 12:50:36 olle
|
||||||
* reorganized prologue and epilogue routines
|
* reorganized prologue and epilogue routines
|
||||||
|
|
||||||
Revision 1.60 2002/10/02 21:49:51 florian
|
Revision 1.60 2002/10/02 21:49:51 florian
|
||||||
|
Loading…
Reference in New Issue
Block a user