* 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:
Jonas Maebe 2015-03-11 17:49:44 +00:00
parent bf7785f567
commit fc21845686
7 changed files with 91 additions and 20 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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
View 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.