|
@@ -1753,9 +1753,12 @@ unit cgcpu;
|
|
|
var
|
|
|
dataregs: tcpuregisterset;
|
|
|
addrregs: tcpuregisterset;
|
|
|
+ fpuregs: tcpuregisterset;
|
|
|
href : treference;
|
|
|
hreg : tregister;
|
|
|
+ hfreg : tregister;
|
|
|
size : longint;
|
|
|
+ fsize : longint;
|
|
|
r : integer;
|
|
|
begin
|
|
|
{ The code generated by the section below, particularly the movem.l
|
|
@@ -1766,10 +1769,13 @@ unit cgcpu;
|
|
|
AS version instead. (KB) }
|
|
|
dataregs:=[];
|
|
|
addrregs:=[];
|
|
|
+ fpuregs:=[];
|
|
|
|
|
|
{ calculate temp. size }
|
|
|
size:=0;
|
|
|
+ fsize:=0;
|
|
|
hreg:=NR_NO;
|
|
|
+ hfreg:=NR_NO;
|
|
|
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
|
|
@@ -1785,14 +1791,22 @@ unit cgcpu;
|
|
|
inc(size,sizeof(aint));
|
|
|
addrregs:=addrregs + [saved_address_registers[r]];
|
|
|
end;
|
|
|
+ if uses_registers(R_FPUREGISTER) then
|
|
|
+ for r:=low(saved_fpu_registers) to high(saved_fpu_registers) do
|
|
|
+ if saved_fpu_registers[r] in rg[R_FPUREGISTER].used_in_proc then
|
|
|
+ begin
|
|
|
+ hfreg:=newreg(R_FPUREGISTER,saved_fpu_registers[r],R_SUBWHOLE);
|
|
|
+ inc(fsize,10{sizeof(extended)});
|
|
|
+ fpuregs:=fpuregs + [saved_fpu_registers[r]];
|
|
|
+ end;
|
|
|
|
|
|
{ 68k has no MM registers }
|
|
|
if uses_registers(R_MMREGISTER) then
|
|
|
internalerror(2014030201);
|
|
|
|
|
|
- if size>0 then
|
|
|
+ if (size+fsize) > 0 then
|
|
|
begin
|
|
|
- tg.GetTemp(list,size,sizeof(aint),tt_noreuse,current_procinfo.save_regs_ref);
|
|
|
+ tg.GetTemp(list,size+fsize,sizeof(aint),tt_noreuse,current_procinfo.save_regs_ref);
|
|
|
include(current_procinfo.flags,pi_has_saved_regs);
|
|
|
|
|
|
{ Copy registers to temp }
|
|
@@ -1804,10 +1818,22 @@ unit cgcpu;
|
|
|
list.concat(taicpu.op_const_reg(A_ADDA,S_L,href.offset,NR_A0));
|
|
|
reference_reset_base(href,NR_A0,0,sizeof(pint));
|
|
|
end;
|
|
|
- if size = sizeof(aint) then
|
|
|
- list.concat(taicpu.op_reg_ref(A_MOVE,S_L,hreg,href))
|
|
|
- else
|
|
|
- list.concat(taicpu.op_regset_ref(A_MOVEM,S_L,dataregs,addrregs,href));
|
|
|
+
|
|
|
+ if size > 0 then
|
|
|
+ if size = sizeof(aint) then
|
|
|
+ list.concat(taicpu.op_reg_ref(A_MOVE,S_L,hreg,href))
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_regset_ref(A_MOVEM,S_L,dataregs,addrregs,[],href));
|
|
|
+
|
|
|
+ if fsize > 0 then
|
|
|
+ begin
|
|
|
+ { size is always longword aligned, while fsize is not }
|
|
|
+ inc(href.offset,size);
|
|
|
+ if fsize = 10{sizeof(extended)} then
|
|
|
+ list.concat(taicpu.op_reg_ref(A_FMOVE,S_FX,hfreg,href))
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_regset_ref(A_FMOVEM,S_FX,[],[],fpuregs,href));
|
|
|
+ end;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -1816,20 +1842,26 @@ unit cgcpu;
|
|
|
var
|
|
|
dataregs: tcpuregisterset;
|
|
|
addrregs: tcpuregisterset;
|
|
|
+ fpuregs : tcpuregisterset;
|
|
|
href : treference;
|
|
|
r : integer;
|
|
|
hreg : tregister;
|
|
|
+ hfreg : tregister;
|
|
|
size : longint;
|
|
|
+ fsize : longint;
|
|
|
begin
|
|
|
{ see the remark about buggy GNU AS versions in g_save_registers() (KB) }
|
|
|
dataregs:=[];
|
|
|
addrregs:=[];
|
|
|
+ fpuregs:=[];
|
|
|
|
|
|
if not(pi_has_saved_regs in current_procinfo.flags) then
|
|
|
exit;
|
|
|
{ Copy registers from temp }
|
|
|
size:=0;
|
|
|
+ fsize:=0;
|
|
|
hreg:=NR_NO;
|
|
|
+ hfreg:=NR_NO;
|
|
|
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
|
|
@@ -1851,6 +1883,17 @@ unit cgcpu;
|
|
|
addrregs:=addrregs + [saved_address_registers[r]];
|
|
|
end;
|
|
|
|
|
|
+ if uses_registers(R_FPUREGISTER) then
|
|
|
+ for r:=low(saved_address_registers) to high(saved_address_registers) do
|
|
|
+ if saved_fpu_registers[r] in rg[R_FPUREGISTER].used_in_proc then
|
|
|
+ begin
|
|
|
+ inc(fsize,10{sizeof(extended)});
|
|
|
+ hfreg:=newreg(R_FPUREGISTER,saved_address_registers[r],R_SUBWHOLE);
|
|
|
+ { Allocate register so the optimizer does not remove the load }
|
|
|
+ a_reg_alloc(list,hfreg);
|
|
|
+ fpuregs:=fpuregs + [saved_fpu_registers[r]];
|
|
|
+ end;
|
|
|
+
|
|
|
{ 68k has no MM registers }
|
|
|
if uses_registers(R_MMREGISTER) then
|
|
|
internalerror(2014030202);
|
|
@@ -1863,10 +1906,22 @@ unit cgcpu;
|
|
|
list.concat(taicpu.op_const_reg(A_ADDA,S_L,href.offset,NR_A0));
|
|
|
reference_reset_base(href,NR_A0,0,sizeof(pint));
|
|
|
end;
|
|
|
- if size = sizeof(aint) then
|
|
|
- list.concat(taicpu.op_ref_reg(A_MOVE,S_L,href,hreg))
|
|
|
- else
|
|
|
- list.concat(taicpu.op_ref_regset(A_MOVEM,S_L,href,dataregs,addrregs));
|
|
|
+
|
|
|
+ if size > 0 then
|
|
|
+ if size = sizeof(aint) then
|
|
|
+ list.concat(taicpu.op_ref_reg(A_MOVE,S_L,href,hreg))
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_ref_regset(A_MOVEM,S_L,href,dataregs,addrregs,[]));
|
|
|
+
|
|
|
+ if fsize > 0 then
|
|
|
+ begin
|
|
|
+ { size is always longword aligned, while fsize is not }
|
|
|
+ inc(href.offset,size);
|
|
|
+ if fsize = 10{sizeof(extended)} then
|
|
|
+ list.concat(taicpu.op_ref_reg(A_FMOVE,S_FX,href,hfreg))
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_ref_regset(A_FMOVEM,S_FX,href,[],[],fpuregs));
|
|
|
+ end;
|
|
|
|
|
|
tg.UnGetTemp(list,current_procinfo.save_regs_ref);
|
|
|
end;
|