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