+ default code now preserves mm registers

* save|restore_standard_registers => save|restore_registers

git-svn-id: trunk@8954 -
This commit is contained in:
florian 2007-10-27 12:02:28 +00:00
parent 3a630340be
commit 00d6a03b2c
16 changed files with 93 additions and 36 deletions

View File

@ -98,8 +98,8 @@ unit cgcpu;
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
procedure g_save_standard_registers(list : TAsmList);override;
procedure g_restore_standard_registers(list : TAsmList);override;
procedure g_save_registers(list : TAsmList);override;
procedure g_restore_registers(list : TAsmList);override;
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
procedure fixref(list : TAsmList;var ref : treference);
@ -1842,13 +1842,13 @@ unit cgcpu;
end;
procedure tcgarm.g_save_standard_registers(list : TAsmList);
procedure tcgarm.g_save_registers(list : TAsmList);
begin
{ this work is done in g_proc_entry }
end;
procedure tcgarm.g_restore_standard_registers(list : TAsmList);
procedure tcgarm.g_restore_registers(list : TAsmList);
begin
{ this work is done in g_proc_exit }
end;

View File

@ -339,6 +339,10 @@ unit cpubase;
}
saved_standard_registers : array[0..6] of tsuperregister =
(RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10);
{ this is only for the generic code which is not used for this architecture }
saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
{ Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.

View File

@ -39,7 +39,7 @@ unit cgobj;
cclasses,globtype,constexp,
cpubase,cgbase,cgutils,parabase,
aasmbase,aasmtai,aasmdata,aasmcpu,
symconst,symbase,symtype,symdef,symtable,rgobj
symconst,symtype,symdef,rgobj
;
type
@ -462,24 +462,25 @@ unit cgobj;
@param(usedinproc Registers which are used in the code of this routine)
}
procedure g_save_standard_registers(list:TAsmList);virtual;
procedure g_save_registers(list:TAsmList);virtual;
{# This routine is called when generating the code for the exit point
of a routine. It should restore all registers which were previously
saved in @var(g_save_standard_registers).
@param(usedinproc Registers which are used in the code of this routine)
}
procedure g_restore_standard_registers(list:TAsmList);virtual;
procedure g_restore_registers(list:TAsmList);virtual;
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract;
procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);virtual;
function g_indirect_sym_load(list:TAsmList;const symname: string): tregister;virtual;
{ generate a stub which only purpose is to pass control the given external method,
{ generate a stub which only purpose is to pass control the given external method,
setting up any additional environment before doing so (if required).
The default implementation issues a jump instruction to the external name. }
procedure g_external_wrapper(list : TAsmList; procdef: tprocdef; const externalname: string); virtual;
{ initialize the pic/got register }
procedure g_maybe_got_init(list: TAsmList); virtual;
protected
@ -3594,17 +3595,26 @@ implementation
end;
procedure tcg.g_save_standard_registers(list:TAsmList);
procedure tcg.g_save_registers(list:TAsmList);
var
href : treference;
size : longint;
r : integer;
begin
{ Get temp }
{ calculate temp. size }
size:=0;
for r:=low(saved_standard_registers) to high(saved_standard_registers) do
if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
inc(size,sizeof(aint));
{ mm registers }
if uses_registers(R_MMREGISTER) then
for r:=low(saved_mm_registers) to high(saved_mm_registers) do
if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
inc(size,tcgsize2size[OS_VECTOR]);
tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
if size>0 then
begin
tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
@ -3620,11 +3630,22 @@ implementation
end;
include(rg[R_INTREGISTER].preserved_by_proc,saved_standard_registers[r]);
end;
if uses_registers(R_MMREGISTER) then
for r:=low(saved_mm_registers) to high(saved_mm_registers) do
begin
if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
begin
a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE),href,nil);
inc(href.offset,tcgsize2size[OS_VECTOR]);
end;
include(rg[R_MMREGISTER].preserved_by_proc,saved_mm_registers[r]);
end;
end;
end;
procedure tcg.g_restore_standard_registers(list:TAsmList);
procedure tcg.g_restore_registers(list:TAsmList);
var
href : treference;
r : integer;
@ -3644,6 +3665,21 @@ implementation
inc(href.offset,sizeof(aint));
freetemp:=true;
end;
if uses_registers(R_MMREGISTER) then
for r:=low(saved_mm_registers) to high(saved_mm_registers) do
begin
if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
begin
hreg:=newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE);
{ Allocate register so the optimizer does not remove the load }
a_reg_alloc(list,hreg);
a_loadmm_ref_reg(list,OS_VECTOR,OS_VECTOR,href,hreg,nil);
inc(href.offset,tcgsize2size[OS_VECTOR]);
freetemp:=true;
end;
end;
if freetemp then
tg.UnGetTemp(list,current_procinfo.save_regs_ref);
end;

View File

@ -159,6 +159,8 @@
GCC source.
}
saved_standard_registers : array[0..2] of tsuperregister = (RS_EBX,RS_ESI,RS_EDI);
saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
{# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.

View File

@ -86,8 +86,8 @@ unit cgcpu;
// procedure g_restore_frame_pointer(list : TAsmList);override;
// procedure g_return_from_proc(list : TAsmList;parasize : aint);override;
procedure g_restore_standard_registers(list:TAsmList);override;
procedure g_save_standard_registers(list:TAsmList);override;
procedure g_restore_registers(list:TAsmList);override;
procedure g_save_registers(list:TAsmList);override;
// procedure g_save_all_registers(list : TAsmList);override;
// procedure g_restore_all_registers(list : TAsmList;const funcretparaloc:TCGPara);override;
@ -1410,7 +1410,7 @@ unit cgcpu;
end;
procedure Tcg68k.g_save_standard_registers(list:TAsmList);
procedure Tcg68k.g_save_registers(list:TAsmList);
var
tosave : tcpuregisterset;
ref : treference;
@ -1427,7 +1427,7 @@ unit cgcpu;
end;
procedure Tcg68k.g_restore_standard_registers(list:TAsmList);
procedure Tcg68k.g_restore_registers(list:TAsmList);
var
torestore : tcpuregisterset;
r:Tregister;

View File

@ -300,6 +300,9 @@ unit cpubase;
}
saved_standard_registers : array[0..5] of tsuperregister = (RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7);
saved_standard_address_registers : array[0..3] of tsuperregister = (RS_A2,RS_A3,RS_A4,RS_A5);
{ this is only for the generic code which is not used for this architecture }
saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
{# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined

View File

@ -353,6 +353,10 @@ unit cpubase;
}
saved_standard_registers : array[0..8] of tsuperregister =
(RS_R16,RS_R17,RS_R18,RS_R19,RS_R20,RS_R21,RS_R22,RS_R23,RS_R30);
{ this is only for the generic code which is not used for this architecture }
saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
{ Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.

View File

@ -2090,7 +2090,7 @@ implementation
{ oldfpccall expects all registers to be destroyed }
if current_procinfo.procdef.proccalloption<>pocall_oldfpccall then
cg.g_save_standard_registers(list);
cg.g_save_registers(list);
end;
@ -2102,7 +2102,7 @@ implementation
{ oldfpccall expects all registers to be destroyed }
if current_procinfo.procdef.proccalloption<>pocall_oldfpccall then
cg.g_restore_standard_registers(list);
cg.g_restore_registers(list);
end;

View File

@ -78,8 +78,8 @@ unit cgcpu;
procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
procedure g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean); override;
procedure g_save_standard_registers(list:TAsmList); override;
procedure g_restore_standard_registers(list:TAsmList); override;
procedure g_save_registers(list:TAsmList); override;
procedure g_restore_registers(list:TAsmList); override;
procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
@ -857,13 +857,13 @@ const
{ *********** entry/exit code and address loading ************ }
procedure tcgppc.g_save_standard_registers(list:TAsmList);
procedure tcgppc.g_save_registers(list:TAsmList);
begin
{ this work is done in g_proc_entry }
end;
procedure tcgppc.g_restore_standard_registers(list:TAsmList);
procedure tcgppc.g_restore_registers(list:TAsmList);
begin
{ this work is done in g_proc_exit }
end;

View File

@ -348,6 +348,9 @@ uses
RS_R30,RS_R31
);
{ this is only for the generic code which is not used for this architecture }
saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
{# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.

View File

@ -90,8 +90,8 @@ type
boolean); override;
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe:
boolean); override;
procedure g_save_standard_registers(list: TAsmList); override;
procedure g_restore_standard_registers(list: TAsmList); override;
procedure g_save_registers(list: TAsmList); override;
procedure g_restore_registers(list: TAsmList); override;
procedure a_loadaddr_ref_reg(list: TAsmList; const ref: treference; r:
tregister); override;
@ -1275,13 +1275,13 @@ end;
{ *********** entry/exit code and address loading ************ }
procedure tcgppc.g_save_standard_registers(list: TAsmList);
procedure tcgppc.g_save_registers(list: TAsmList);
begin
{ this work is done in g_proc_entry; additionally it is not safe
to use it because it is called at some weird time }
end;
procedure tcgppc.g_restore_standard_registers(list: TAsmList);
procedure tcgppc.g_restore_registers(list: TAsmList);
begin
{ this work is done in g_proc_exit; mainly because it is not safe to
put the register restore code here because it is called at some weird time }

View File

@ -348,6 +348,9 @@ const
RS_R26, RS_R27, RS_R28, RS_R29, RS_R30, RS_R31
);
{ this is only for the generic code which is not used for this architecture }
saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
{# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.

View File

@ -84,8 +84,8 @@ interface
procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
procedure g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean);override;
procedure g_restore_standard_registers(list:TAsmList);override;
procedure g_save_standard_registers(list : TAsmList);override;
procedure g_restore_registers(list:TAsmList);override;
procedure g_save_registers(list : TAsmList);override;
procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
procedure g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);override;
procedure g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint);
@ -1065,7 +1065,7 @@ implementation
end;
procedure TCgSparc.g_restore_standard_registers(list:TAsmList);
procedure TCgSparc.g_restore_registers(list:TAsmList);
begin
{ The sparc port uses the sparc standard calling convetions so this function has no used }
end;
@ -1114,7 +1114,7 @@ implementation
end;
procedure TCgSparc.g_save_standard_registers(list : TAsmList);
procedure TCgSparc.g_save_registers(list : TAsmList);
begin
{ The sparc port uses the sparc standard calling convetions so this function has no used }
end;

View File

@ -304,6 +304,9 @@ uses
}
saved_standard_registers : array[0..0] of tsuperregister = (RS_NO);
{ this is only for the generic code which is not used for this architecture }
saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
{# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.

View File

@ -65,24 +65,24 @@ unit cgcpu;
if target_info.system=system_x86_64_win64 then
begin
SetLength(saved_standard_registers,Length(win64_saved_std_regs));
SetLength(saved_xmm_registers,Length(win64_saved_xmm_regs));
SetLength(saved_mm_registers,Length(win64_saved_xmm_regs));
for i:=low(win64_saved_std_regs) to high(win64_saved_std_regs) do
saved_standard_registers[i]:=win64_saved_std_regs[i];
for i:=low(win64_saved_xmm_regs) to high(win64_saved_xmm_regs) do
saved_xmm_registers[i]:=win64_saved_xmm_regs[i];
saved_mm_registers[i]:=win64_saved_xmm_regs[i];
end
else
begin
SetLength(saved_standard_registers,Length(others_saved_std_regs));
SetLength(saved_xmm_registers,0);
SetLength(saved_mm_registers,0);
for i:=low(others_saved_std_regs) to high(others_saved_std_regs) do
saved_standard_registers[i]:=others_saved_std_regs[i];
end;
if assigned(current_procinfo) then
framepointer:=getsupreg(current_procinfo.framepointer)
framepointer:=getsupreg(current_procinfo.framepointer)
else
{ in intf. wrapper code generation }
framepointer:=RS_FRAME_POINTER_REG;

View File

@ -123,7 +123,7 @@ const
const
{ these arrays differ between unix and win64 }
saved_standard_registers : array of tsuperregister = nil;
saved_xmm_registers : array of tsuperregister = nil;
saved_mm_registers : array of tsuperregister = nil;
{ Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.
@ -132,4 +132,3 @@ const
PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
}
std_param_align = 8;