mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 04:59:26 +02:00
m68k implementation of g_save_registers and g_restore_registers using movem.l
git-svn-id: trunk@26923 -
This commit is contained in:
parent
ae28ecd5f8
commit
1d5f74fae0
@ -85,8 +85,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_restore_frame_pointer(list : TAsmList);override;
|
||||
// procedure g_return_from_proc(list : TAsmList;parasize : tcgint);override;
|
||||
procedure g_save_registers(list:TAsmList);override;
|
||||
procedure g_restore_registers(list:TAsmList);override;
|
||||
|
||||
procedure g_adjust_self_value(list:TAsmList;procdef:tprocdef;ioffset:tcgint);override;
|
||||
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
|
||||
@ -1752,6 +1752,114 @@ unit cgcpu;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg68k.g_save_registers(list:TAsmList);
|
||||
var
|
||||
dataregs: tcpuregisterset;
|
||||
addrregs: tcpuregisterset;
|
||||
href : treference;
|
||||
hreg : tregister;
|
||||
size : longint;
|
||||
r : integer;
|
||||
begin
|
||||
{ The code generated by the section below, particularly the movem.l
|
||||
instruction is known to cause an issue when compiled by some GNU
|
||||
assembler versions (I had it with 2.17, while 2.24 seems OK.)
|
||||
when you run into this problem, just call inherited here instead
|
||||
to skip the movem.l generation. But better just use working GNU
|
||||
AS version instead. (KB) }
|
||||
dataregs:=[];
|
||||
addrregs:=[];
|
||||
|
||||
{ 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
|
||||
begin
|
||||
hreg:=newreg(R_INTREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
||||
inc(size,sizeof(aint));
|
||||
dataregs:=dataregs + [saved_standard_registers[r]];
|
||||
end;
|
||||
if uses_registers(R_ADDRESSREGISTER) then
|
||||
for r:=low(saved_address_registers) to high(saved_address_registers) do
|
||||
if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
|
||||
begin
|
||||
hreg:=newreg(R_ADDRESSREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
||||
inc(size,sizeof(aint));
|
||||
addrregs:=addrregs + [saved_address_registers[r]];
|
||||
end;
|
||||
|
||||
{ 68k has no MM registers }
|
||||
if uses_registers(R_MMREGISTER) then
|
||||
internalerror(2014030201);
|
||||
|
||||
if size>0 then
|
||||
begin
|
||||
tg.GetTemp(list,size,sizeof(aint),tt_noreuse,current_procinfo.save_regs_ref);
|
||||
include(current_procinfo.flags,pi_has_saved_regs);
|
||||
|
||||
{ Copy registers to temp }
|
||||
href:=current_procinfo.save_regs_ref;
|
||||
if size = sizeof(aint) then
|
||||
a_load_reg_ref(list, OS_32, OS_32, hreg, href)
|
||||
else
|
||||
list.concat(taicpu.op_regset_ref(A_MOVEM,S_L,dataregs,addrregs,href));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg68k.g_restore_registers(list:TAsmList);
|
||||
var
|
||||
dataregs: tcpuregisterset;
|
||||
addrregs: tcpuregisterset;
|
||||
href : treference;
|
||||
r : integer;
|
||||
hreg : tregister;
|
||||
size : longint;
|
||||
begin
|
||||
{ see the remark about buggy GNU AS versions in g_save_registers() (KB) }
|
||||
dataregs:=[];
|
||||
addrregs:=[];
|
||||
|
||||
if not(pi_has_saved_regs in current_procinfo.flags) then
|
||||
exit;
|
||||
{ Copy registers from temp }
|
||||
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
|
||||
begin
|
||||
inc(size,sizeof(aint));
|
||||
hreg:=newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE);
|
||||
{ Allocate register so the optimizer does not remove the load }
|
||||
a_reg_alloc(list,hreg);
|
||||
dataregs:=dataregs + [saved_standard_registers[r]];
|
||||
end;
|
||||
|
||||
if uses_registers(R_ADDRESSREGISTER) then
|
||||
for r:=low(saved_address_registers) to high(saved_address_registers) do
|
||||
if saved_address_registers[r] in rg[R_ADDRESSREGISTER].used_in_proc then
|
||||
begin
|
||||
inc(size,sizeof(aint));
|
||||
hreg:=newreg(R_ADDRESSREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
||||
{ Allocate register so the optimizer does not remove the load }
|
||||
a_reg_alloc(list,hreg);
|
||||
addrregs:=addrregs + [saved_address_registers[r]];
|
||||
end;
|
||||
|
||||
{ 68k has no MM registers }
|
||||
if uses_registers(R_MMREGISTER) then
|
||||
internalerror(2014030202);
|
||||
|
||||
{ Restore registers from temp }
|
||||
href:=current_procinfo.save_regs_ref;
|
||||
if size = sizeof(aint) then
|
||||
a_load_ref_reg(list, OS_32, OS_32, href, hreg)
|
||||
else
|
||||
list.concat(taicpu.op_ref_regset(A_MOVEM,S_L,href,dataregs,addrregs));
|
||||
|
||||
tg.UnGetTemp(list,current_procinfo.save_regs_ref);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg68k.sign_extend(list: TAsmList;_oldsize : tcgsize; reg: tregister);
|
||||
begin
|
||||
case _oldsize of
|
||||
|
Loading…
Reference in New Issue
Block a user