mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-06 16:16:03 +02:00
* fixed the allocation of R12 on ppc32/ppc64 when used to hold the value of
the stack pointer during the prolog. This was done previously in tcg.g_proc_entry(), but that routine is called after register allocation and hence has no influence. Also cleaned up the deallocation of that register by moving the previously ifdef'd code to thlcgppcgen (mantis #27634) git-svn-id: trunk@30164 -
This commit is contained in:
parent
bf7785f567
commit
fc21845686
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -14319,6 +14319,7 @@ tests/webtbs/tw27424.pp svneol=native#text/pascal
|
|||||||
tests/webtbs/tw27515.pp svneol=native#text/pascal
|
tests/webtbs/tw27515.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw2758.pp svneol=native#text/plain
|
tests/webtbs/tw2758.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2763.pp svneol=native#text/plain
|
tests/webtbs/tw2763.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw27634.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2765.pp svneol=native#text/plain
|
tests/webtbs/tw2765.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2767.pp svneol=native#text/plain
|
tests/webtbs/tw2767.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw2771.pp svneol=native#text/plain
|
tests/webtbs/tw2771.pp svneol=native#text/plain
|
||||||
|
@ -1259,18 +1259,6 @@ implementation
|
|||||||
the initialization and body is parsed because the refcounts are
|
the initialization and body is parsed because the refcounts are
|
||||||
incremented using the local copies }
|
incremented using the local copies }
|
||||||
current_procinfo.procdef.parast.SymList.ForEachCall(@hlcg.g_copyvalueparas,list);
|
current_procinfo.procdef.parast.SymList.ForEachCall(@hlcg.g_copyvalueparas,list);
|
||||||
{$ifdef powerpc}
|
|
||||||
{ unget the register that contains the stack pointer before the procedure entry, }
|
|
||||||
{ which is used to access the parameters in their original callee-side location }
|
|
||||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
|
||||||
cg.a_reg_dealloc(list,NR_R12);
|
|
||||||
{$endif powerpc}
|
|
||||||
{$ifdef powerpc64}
|
|
||||||
{ unget the register that contains the stack pointer before the procedure entry, }
|
|
||||||
{ which is used to access the parameters in their original callee-side location }
|
|
||||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
|
||||||
cg.a_reg_dealloc(list, NR_OLD_STACK_POINTER_REG);
|
|
||||||
{$endif powerpc64}
|
|
||||||
if not(po_assembler in current_procinfo.procdef.procoptions) then
|
if not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||||
begin
|
begin
|
||||||
{ initialize refcounted paras, and trash others. Needed here
|
{ initialize refcounted paras, and trash others. Needed here
|
||||||
|
@ -830,11 +830,8 @@ const
|
|||||||
usesgpr := firstregint <> 32;
|
usesgpr := firstregint <> 32;
|
||||||
usesfpr := firstregfpu <> 32;
|
usesfpr := firstregfpu <> 32;
|
||||||
|
|
||||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
if tppcprocinfo(current_procinfo).needs_frame_pointer then
|
||||||
begin
|
list.concat(taicpu.op_reg_reg(A_MR,NR_OLD_STACK_POINTER_REG,NR_STACK_POINTER_REG));
|
||||||
a_reg_alloc(list,NR_R12);
|
|
||||||
list.concat(taicpu.op_reg_reg(A_MR,NR_R12,NR_STACK_POINTER_REG));
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if usesfpr then
|
if usesfpr then
|
||||||
|
@ -291,6 +291,10 @@ uses
|
|||||||
{# Stack pointer register }
|
{# Stack pointer register }
|
||||||
NR_STACK_POINTER_REG = NR_R1;
|
NR_STACK_POINTER_REG = NR_R1;
|
||||||
RS_STACK_POINTER_REG = RS_R1;
|
RS_STACK_POINTER_REG = RS_R1;
|
||||||
|
{ old stack pointer register used during copying variables from the caller
|
||||||
|
stack frame
|
||||||
|
}
|
||||||
|
NR_OLD_STACK_POINTER_REG = NR_R12;
|
||||||
{# Frame pointer register }
|
{# Frame pointer register }
|
||||||
NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
|
NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
|
||||||
RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
|
RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
|
||||||
|
@ -1193,10 +1193,8 @@ begin
|
|||||||
save_standard_registers;
|
save_standard_registers;
|
||||||
|
|
||||||
{ save old stack frame pointer }
|
{ save old stack frame pointer }
|
||||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then begin
|
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
||||||
a_reg_alloc(list, NR_OLD_STACK_POINTER_REG);
|
|
||||||
list.concat(taicpu.op_reg_reg(A_MR, NR_OLD_STACK_POINTER_REG, NR_STACK_POINTER_REG));
|
list.concat(taicpu.op_reg_reg(A_MR, NR_OLD_STACK_POINTER_REG, NR_STACK_POINTER_REG));
|
||||||
end;
|
|
||||||
|
|
||||||
{ create stack frame }
|
{ create stack frame }
|
||||||
if (not nostackframe) and (localsize > 0) and
|
if (not nostackframe) and (localsize > 0) and
|
||||||
|
@ -36,12 +36,15 @@ type
|
|||||||
thlcgppcgen = class(thlcg2ll)
|
thlcgppcgen = class(thlcg2ll)
|
||||||
protected
|
protected
|
||||||
procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tdef; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
|
procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tdef; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
|
||||||
|
public
|
||||||
|
procedure gen_load_para_value(list: TAsmList); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
cpubase,globtype,
|
cpubase,globtype,
|
||||||
|
procinfo,cpupi,
|
||||||
symdef,defutil;
|
symdef,defutil;
|
||||||
|
|
||||||
{ thlcgppc }
|
{ thlcgppc }
|
||||||
@ -80,5 +83,19 @@ implementation
|
|||||||
a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
|
a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure thlcgppcgen.gen_load_para_value(list: TAsmList);
|
||||||
|
begin
|
||||||
|
{ get the register that contains the stack pointer before the procedure
|
||||||
|
entry, which is used to access the parameters in their original
|
||||||
|
callee-side location }
|
||||||
|
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
||||||
|
getcpuregister(list,NR_OLD_STACK_POINTER_REG);
|
||||||
|
inherited;
|
||||||
|
{ free it again }
|
||||||
|
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
||||||
|
ungetcpuregister(list,NR_OLD_STACK_POINTER_REG);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
66
tests/webtbs/tw27634.pp
Normal file
66
tests/webtbs/tw27634.pp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
type
|
||||||
|
MBHelpPtr = pointer;
|
||||||
|
MenuRecord = record end;
|
||||||
|
MenuItemsPtr = pointer;
|
||||||
|
MenuIconHandle = pointer;
|
||||||
|
MenuRef = pointer;
|
||||||
|
int16 = word;
|
||||||
|
int32 = longint;
|
||||||
|
OSStatus = int32;
|
||||||
|
Str255 = ShortString;
|
||||||
|
|
||||||
|
function MacMenuAddItemInternal
|
||||||
|
( var theMenuRecord : MenuRecord;
|
||||||
|
theMenuOrSubMenuID : Int32;
|
||||||
|
theOptBeforeItemIndex : Int32;
|
||||||
|
var theMenuRef : MenuRef;
|
||||||
|
var theItemsPtr : MenuItemsPtr;
|
||||||
|
const theItemStr : Str255;
|
||||||
|
theItemIconHandle : MenuIconHandle;
|
||||||
|
theEnableFlag : boolean;
|
||||||
|
theCheckFlag : boolean;
|
||||||
|
theCommandChar : char;
|
||||||
|
theCommandModifiers : Int16;
|
||||||
|
theItemCmdID : Int32;
|
||||||
|
const theItemAppStr : AnsiString;
|
||||||
|
var theNewItemIndex : Int32): OSStatus;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
function MBMenuAddItemInternal
|
||||||
|
( var theMenuRecord : MenuRecord;
|
||||||
|
theMenuOrSubMenuID : Int32;
|
||||||
|
theOptBeforeItemIndex : Int32;
|
||||||
|
var theMenuRef : MenuRef;
|
||||||
|
var theItemsPtr : MenuItemsPtr;
|
||||||
|
const theItemStr : Str255;
|
||||||
|
theItemIconHandle : MenuIconHandle;
|
||||||
|
theEnableFlag : boolean;
|
||||||
|
theCheckFlag : boolean;
|
||||||
|
theCommandChar : char;
|
||||||
|
theCommandGlyph : Int16; { unused here }
|
||||||
|
theCommandModifiers : Int16;
|
||||||
|
theItemCmdID : Int32;
|
||||||
|
const theItemAppStr : AnsiString;
|
||||||
|
theItemHelpPtr : MBHelpPtr; { unused here }
|
||||||
|
var theNewItemIndex : Int32): OSStatus;
|
||||||
|
var
|
||||||
|
theErr : OSStatus;
|
||||||
|
begin
|
||||||
|
theItemsPtr := nil;
|
||||||
|
theNewItemIndex := 0;
|
||||||
|
theErr := MacMenuAddItemInternal
|
||||||
|
( theMenuRecord, theMenuOrSubMenuID, theOptBeforeItemIndex, theMenuRef, theItemsPtr,
|
||||||
|
theItemStr, theItemIconHandle, theEnableFlag, theCheckFlag, theCommandChar,
|
||||||
|
theCommandModifiers, theItemCmdID, theItemAppStr, theNewItemIndex);
|
||||||
|
MBMenuAddItemInternal := theErr
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
theMenuRecord: MenuRecord;
|
||||||
|
theMenuRef: MenuRef;
|
||||||
|
theItemsPtr: MenuItemsPtr;
|
||||||
|
theNewItemIndex: Int32;
|
||||||
|
begin
|
||||||
|
MBMenuAddItemInternal(theMenuRecord,1,2,theMenuRef,theItemsPtr,'abc',nil,true,false,'b',3,4,5,'def',nil,theNewItemIndex);
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user