mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 09:59:25 +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/tw2758.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/tw2767.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
|
||||
incremented using the local copies }
|
||||
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
|
||||
begin
|
||||
{ initialize refcounted paras, and trash others. Needed here
|
||||
|
@ -830,11 +830,8 @@ const
|
||||
usesgpr := firstregint <> 32;
|
||||
usesfpr := firstregfpu <> 32;
|
||||
|
||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
||||
begin
|
||||
a_reg_alloc(list,NR_R12);
|
||||
list.concat(taicpu.op_reg_reg(A_MR,NR_R12,NR_STACK_POINTER_REG));
|
||||
end;
|
||||
if tppcprocinfo(current_procinfo).needs_frame_pointer then
|
||||
list.concat(taicpu.op_reg_reg(A_MR,NR_OLD_STACK_POINTER_REG,NR_STACK_POINTER_REG));
|
||||
end;
|
||||
|
||||
if usesfpr then
|
||||
|
@ -291,6 +291,10 @@ uses
|
||||
{# Stack pointer register }
|
||||
NR_STACK_POINTER_REG = NR_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 }
|
||||
NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
|
||||
RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
|
||||
|
@ -1193,10 +1193,8 @@ begin
|
||||
save_standard_registers;
|
||||
|
||||
{ save old stack frame pointer }
|
||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then begin
|
||||
a_reg_alloc(list, NR_OLD_STACK_POINTER_REG);
|
||||
if (tppcprocinfo(current_procinfo).needs_frame_pointer) then
|
||||
list.concat(taicpu.op_reg_reg(A_MR, NR_OLD_STACK_POINTER_REG, NR_STACK_POINTER_REG));
|
||||
end;
|
||||
|
||||
{ create stack frame }
|
||||
if (not nostackframe) and (localsize > 0) and
|
||||
|
@ -36,12 +36,15 @@ type
|
||||
thlcgppcgen = class(thlcg2ll)
|
||||
protected
|
||||
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;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
cpubase,globtype,
|
||||
procinfo,cpupi,
|
||||
symdef,defutil;
|
||||
|
||||
{ thlcgppc }
|
||||
@ -80,5 +83,19 @@ implementation
|
||||
a_load_subsetreg_subsetreg(list,subsetsize,subsetsize,fromsreg,tosreg);
|
||||
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.
|
||||
|
||||
|
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