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

View File

@ -339,6 +339,10 @@ unit cpubase;
} }
saved_standard_registers : array[0..6] of tsuperregister = saved_standard_registers : array[0..6] of tsuperregister =
(RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10); (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 { Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI. by GCC or the target ABI.

View File

@ -39,7 +39,7 @@ unit cgobj;
cclasses,globtype,constexp, cclasses,globtype,constexp,
cpubase,cgbase,cgutils,parabase, cpubase,cgbase,cgutils,parabase,
aasmbase,aasmtai,aasmdata,aasmcpu, aasmbase,aasmtai,aasmdata,aasmcpu,
symconst,symbase,symtype,symdef,symtable,rgobj symconst,symtype,symdef,rgobj
; ;
type type
@ -462,14 +462,15 @@ unit cgobj;
@param(usedinproc Registers which are used in the code of this routine) @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 {# This routine is called when generating the code for the exit point
of a routine. It should restore all registers which were previously of a routine. It should restore all registers which were previously
saved in @var(g_save_standard_registers). saved in @var(g_save_standard_registers).
@param(usedinproc Registers which are used in the code of this routine) @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_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; procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);virtual;
@ -3594,17 +3595,26 @@ implementation
end; end;
procedure tcg.g_save_standard_registers(list:TAsmList); procedure tcg.g_save_registers(list:TAsmList);
var var
href : treference; href : treference;
size : longint; size : longint;
r : integer; r : integer;
begin begin
{ Get temp } { calculate temp. size }
size:=0; size:=0;
for r:=low(saved_standard_registers) to high(saved_standard_registers) do 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 if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
inc(size,sizeof(aint)); 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 if size>0 then
begin begin
tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref); tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
@ -3620,11 +3630,22 @@ implementation
end; end;
include(rg[R_INTREGISTER].preserved_by_proc,saved_standard_registers[r]); include(rg[R_INTREGISTER].preserved_by_proc,saved_standard_registers[r]);
end; 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;
end; end;
procedure tcg.g_restore_standard_registers(list:TAsmList); procedure tcg.g_restore_registers(list:TAsmList);
var var
href : treference; href : treference;
r : integer; r : integer;
@ -3644,6 +3665,21 @@ implementation
inc(href.offset,sizeof(aint)); inc(href.offset,sizeof(aint));
freetemp:=true; freetemp:=true;
end; 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 if freetemp then
tg.UnGetTemp(list,current_procinfo.save_regs_ref); tg.UnGetTemp(list,current_procinfo.save_regs_ref);
end; end;

View File

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

View File

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

View File

@ -301,6 +301,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_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); 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 {# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI. by GCC or the target ABI.

View File

@ -353,6 +353,10 @@ unit cpubase;
} }
saved_standard_registers : array[0..8] of tsuperregister = 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); (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 { Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI. by GCC or the target ABI.

View File

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

View File

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

View File

@ -348,6 +348,9 @@ uses
RS_R30,RS_R31 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 {# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI. by GCC or the target ABI.

View File

@ -90,8 +90,8 @@ type
boolean); override; boolean); override;
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe:
boolean); override; boolean); override;
procedure g_save_standard_registers(list: TAsmList); override; procedure g_save_registers(list: TAsmList); override;
procedure g_restore_standard_registers(list: TAsmList); override; procedure g_restore_registers(list: TAsmList); override;
procedure a_loadaddr_ref_reg(list: TAsmList; const ref: treference; r: procedure a_loadaddr_ref_reg(list: TAsmList; const ref: treference; r:
tregister); override; tregister); override;
@ -1275,13 +1275,13 @@ end;
{ *********** entry/exit code and address loading ************ } { *********** entry/exit code and address loading ************ }
procedure tcgppc.g_save_standard_registers(list: TAsmList); procedure tcgppc.g_save_registers(list: TAsmList);
begin begin
{ this work is done in g_proc_entry; additionally it is not safe { this work is done in g_proc_entry; additionally it is not safe
to use it because it is called at some weird time } to use it because it is called at some weird time }
end; end;
procedure tcgppc.g_restore_standard_registers(list: TAsmList); procedure tcgppc.g_restore_registers(list: TAsmList);
begin begin
{ this work is done in g_proc_exit; mainly because it is not safe to { 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 } 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 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 {# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI. 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_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_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
procedure g_proc_exit(list : TAsmList;parasize: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_restore_registers(list:TAsmList);override;
procedure g_save_standard_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(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_unaligned(list : TAsmList;const source,dest : treference;len : aint);override;
procedure g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint); procedure g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint);
@ -1065,7 +1065,7 @@ implementation
end; end;
procedure TCgSparc.g_restore_standard_registers(list:TAsmList); procedure TCgSparc.g_restore_registers(list:TAsmList);
begin begin
{ The sparc port uses the sparc standard calling convetions so this function has no used } { The sparc port uses the sparc standard calling convetions so this function has no used }
end; end;
@ -1114,7 +1114,7 @@ implementation
end; end;
procedure TCgSparc.g_save_standard_registers(list : TAsmList); procedure TCgSparc.g_save_registers(list : TAsmList);
begin begin
{ The sparc port uses the sparc standard calling convetions so this function has no used } { The sparc port uses the sparc standard calling convetions so this function has no used }
end; end;

View File

@ -304,6 +304,9 @@ uses
} }
saved_standard_registers : array[0..0] of tsuperregister = (RS_NO); 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 {# Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI. by GCC or the target ABI.

View File

@ -65,18 +65,18 @@ unit cgcpu;
if target_info.system=system_x86_64_win64 then if target_info.system=system_x86_64_win64 then
begin begin
SetLength(saved_standard_registers,Length(win64_saved_std_regs)); 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 for i:=low(win64_saved_std_regs) to high(win64_saved_std_regs) do
saved_standard_registers[i]:=win64_saved_std_regs[i]; saved_standard_registers[i]:=win64_saved_std_regs[i];
for i:=low(win64_saved_xmm_regs) to high(win64_saved_xmm_regs) do 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 end
else else
begin begin
SetLength(saved_standard_registers,Length(others_saved_std_regs)); 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 for i:=low(others_saved_std_regs) to high(others_saved_std_regs) do
saved_standard_registers[i]:=others_saved_std_regs[i]; saved_standard_registers[i]:=others_saved_std_regs[i];

View File

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