|
@@ -65,42 +65,12 @@ unit cgcpu;
|
|
|
|
|
|
|
|
|
|
procedure Tcgx86_64.init_register_allocators;
|
|
procedure Tcgx86_64.init_register_allocators;
|
|
- const
|
|
|
|
- win64_saved_std_regs : array[0..7] of tsuperregister = (RS_RBX,RS_RDI,RS_RSI,RS_R12,RS_R13,RS_R14,RS_R15,RS_RBP);
|
|
|
|
- others_saved_std_regs : array[0..4] of tsuperregister = (RS_RBX,RS_R12,RS_R13,RS_R14,RS_R15);
|
|
|
|
- saved_regs_length : array[boolean] of longint = (5,7);
|
|
|
|
-
|
|
|
|
- win64_saved_xmm_regs : array[0..9] of tsuperregister = (RS_XMM6,RS_XMM7,
|
|
|
|
- RS_XMM8,RS_XMM9,RS_XMM10,RS_XMM11,RS_XMM12,RS_XMM13,RS_XMM14,RS_XMM15);
|
|
|
|
var
|
|
var
|
|
- i : longint;
|
|
|
|
ms_abi: boolean;
|
|
ms_abi: boolean;
|
|
begin
|
|
begin
|
|
inherited init_register_allocators;
|
|
inherited init_register_allocators;
|
|
|
|
|
|
ms_abi:=use_ms_abi;
|
|
ms_abi:=use_ms_abi;
|
|
- if (length(saved_standard_registers)<>saved_regs_length[ms_abi]) then
|
|
|
|
- begin
|
|
|
|
- if ms_abi then
|
|
|
|
- begin
|
|
|
|
- SetLength(saved_standard_registers,Length(win64_saved_std_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_mm_registers[i]:=win64_saved_xmm_regs[i];
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- begin
|
|
|
|
- SetLength(saved_standard_registers,Length(others_saved_std_regs));
|
|
|
|
- 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;
|
|
|
|
- end;
|
|
|
|
if ms_abi then
|
|
if ms_abi then
|
|
begin
|
|
begin
|
|
if (cs_userbp in current_settings.optimizerswitches) and assigned(current_procinfo) and (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
|
if (cs_userbp in current_settings.optimizerswitches) and assigned(current_procinfo) and (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
|
@@ -156,14 +126,16 @@ unit cgcpu;
|
|
function tcgx86_64.saved_xmm_reg_size: longint;
|
|
function tcgx86_64.saved_xmm_reg_size: longint;
|
|
var
|
|
var
|
|
i: longint;
|
|
i: longint;
|
|
|
|
+ regs_to_save_mm: tcpuregisterarray;
|
|
begin
|
|
begin
|
|
result:=0;
|
|
result:=0;
|
|
if (target_info.system<>system_x86_64_win64) or
|
|
if (target_info.system<>system_x86_64_win64) or
|
|
(not uses_registers(R_MMREGISTER)) then
|
|
(not uses_registers(R_MMREGISTER)) then
|
|
exit;
|
|
exit;
|
|
- for i:=low(saved_mm_registers) to high(saved_mm_registers) do
|
|
|
|
|
|
+ regs_to_save_mm:=paramanager.get_saved_registers_mm(current_procinfo.procdef.proccalloption);
|
|
|
|
+ for i:=low(regs_to_save_mm) to high(regs_to_save_mm) do
|
|
begin
|
|
begin
|
|
- if (saved_mm_registers[i] in rg[R_MMREGISTER].used_in_proc) then
|
|
|
|
|
|
+ if (regs_to_save_mm[i] in rg[R_MMREGISTER].used_in_proc) then
|
|
inc(result,tcgsize2size[OS_VECTOR]);
|
|
inc(result,tcgsize2size[OS_VECTOR]);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -180,6 +152,8 @@ unit cgcpu;
|
|
suppress_endprologue: boolean;
|
|
suppress_endprologue: boolean;
|
|
stackmisalignment: longint;
|
|
stackmisalignment: longint;
|
|
xmmsize: longint;
|
|
xmmsize: longint;
|
|
|
|
+ regs_to_save_int,
|
|
|
|
+ regs_to_save_mm: tcpuregisterarray;
|
|
|
|
|
|
procedure push_one_reg(reg: tregister);
|
|
procedure push_one_reg(reg: tregister);
|
|
begin
|
|
begin
|
|
@@ -197,15 +171,17 @@ unit cgcpu;
|
|
usedregs: tcpuregisterset;
|
|
usedregs: tcpuregisterset;
|
|
begin
|
|
begin
|
|
usedregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
|
|
usedregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption);
|
|
- for r := low(saved_standard_registers) to high(saved_standard_registers) do
|
|
|
|
- if saved_standard_registers[r] in usedregs then
|
|
|
|
|
|
+ for r := low(regs_to_save_int) to high(regs_to_save_int) do
|
|
|
|
+ if regs_to_save_int[r] in usedregs then
|
|
begin
|
|
begin
|
|
inc(stackmisalignment,sizeof(pint));
|
|
inc(stackmisalignment,sizeof(pint));
|
|
- push_one_reg(newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE));
|
|
|
|
|
|
+ push_one_reg(newreg(R_INTREGISTER,regs_to_save_int[r],R_SUBWHOLE));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
begin
|
|
begin
|
|
|
|
+ regs_to_save_int:=paramanager.get_saved_registers_int(current_procinfo.procdef.proccalloption);
|
|
|
|
+ regs_to_save_mm:=paramanager.get_saved_registers_mm(current_procinfo.procdef.proccalloption);
|
|
hitem:=list.last;
|
|
hitem:=list.last;
|
|
{ pi_has_unwind_info may already be set at this point if there are
|
|
{ pi_has_unwind_info may already be set at this point if there are
|
|
SEH directives in assembler body. In this case, .seh_endprologue
|
|
SEH directives in assembler body. In this case, .seh_endprologue
|
|
@@ -282,10 +258,10 @@ unit cgcpu;
|
|
if use_push and (xmmsize<>0) then
|
|
if use_push and (xmmsize<>0) then
|
|
begin
|
|
begin
|
|
href:=current_procinfo.save_regs_ref;
|
|
href:=current_procinfo.save_regs_ref;
|
|
- 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
|
|
|
|
|
|
+ for r:=low(regs_to_save_mm) to high(regs_to_save_mm) do
|
|
|
|
+ if regs_to_save_mm[r] in rg[R_MMREGISTER].used_in_proc then
|
|
begin
|
|
begin
|
|
- a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBMMWHOLE),href,nil);
|
|
|
|
|
|
+ a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,regs_to_save_mm[r],R_SUBMMWHOLE),href,nil);
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]);
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -316,11 +292,11 @@ unit cgcpu;
|
|
href:=current_procinfo.save_regs_ref;
|
|
href:=current_procinfo.save_regs_ref;
|
|
if (not use_push) then
|
|
if (not use_push) then
|
|
begin
|
|
begin
|
|
- 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
|
|
|
|
|
|
+ for r:=low(regs_to_save_int) to high(regs_to_save_int) do
|
|
|
|
+ if regs_to_save_int[r] in rg[R_INTREGISTER].used_in_proc then
|
|
begin
|
|
begin
|
|
templist.concat(cai_seh_directive.create_reg_offset(ash_savereg,
|
|
templist.concat(cai_seh_directive.create_reg_offset(ash_savereg,
|
|
- newreg(R_INTREGISTER,saved_standard_registers[r],R_SUBWHOLE),
|
|
|
|
|
|
+ newreg(R_INTREGISTER,regs_to_save_int[r],R_SUBWHOLE),
|
|
href.offset+frame_offset));
|
|
href.offset+frame_offset));
|
|
inc(href.offset,sizeof(aint));
|
|
inc(href.offset,sizeof(aint));
|
|
end;
|
|
end;
|
|
@@ -330,12 +306,12 @@ unit cgcpu;
|
|
if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then
|
|
if (href.offset mod tcgsize2size[OS_VECTOR])<>0 then
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]-(href.offset mod tcgsize2size[OS_VECTOR]));
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]-(href.offset mod tcgsize2size[OS_VECTOR]));
|
|
|
|
|
|
- for r:=low(saved_mm_registers) to high(saved_mm_registers) do
|
|
|
|
|
|
+ for r:=low(regs_to_save_mm) to high(regs_to_save_mm) do
|
|
begin
|
|
begin
|
|
- if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
|
|
|
|
|
|
+ if regs_to_save_mm[r] in rg[R_MMREGISTER].used_in_proc then
|
|
begin
|
|
begin
|
|
templist.concat(cai_seh_directive.create_reg_offset(ash_savexmm,
|
|
templist.concat(cai_seh_directive.create_reg_offset(ash_savexmm,
|
|
- newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBMMWHOLE),
|
|
|
|
|
|
+ newreg(R_MMREGISTER,regs_to_save_mm[r],R_SUBMMWHOLE),
|
|
href.offset+frame_offset));
|
|
href.offset+frame_offset));
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]);
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]);
|
|
end;
|
|
end;
|
|
@@ -366,7 +342,9 @@ unit cgcpu;
|
|
href : treference;
|
|
href : treference;
|
|
hreg : tregister;
|
|
hreg : tregister;
|
|
r : longint;
|
|
r : longint;
|
|
|
|
+ regs_to_save_mm: tcpuregisterarray;
|
|
begin
|
|
begin
|
|
|
|
+ regs_to_save_mm:=paramanager.get_saved_registers_mm(current_procinfo.procdef.proccalloption);;
|
|
{ Prevent return address from a possible call from ending up in the epilogue }
|
|
{ Prevent return address from a possible call from ending up in the epilogue }
|
|
{ (restoring registers happens before epilogue, providing necessary padding) }
|
|
{ (restoring registers happens before epilogue, providing necessary padding) }
|
|
if (current_procinfo.flags*[pi_has_unwind_info,pi_do_call,pi_has_saved_regs])=[pi_has_unwind_info,pi_do_call] then
|
|
if (current_procinfo.flags*[pi_has_unwind_info,pi_do_call,pi_has_saved_regs])=[pi_has_unwind_info,pi_do_call] then
|
|
@@ -379,11 +357,11 @@ unit cgcpu;
|
|
if (saved_xmm_reg_size<>0) then
|
|
if (saved_xmm_reg_size<>0) then
|
|
begin
|
|
begin
|
|
href:=current_procinfo.save_regs_ref;
|
|
href:=current_procinfo.save_regs_ref;
|
|
- 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
|
|
|
|
|
|
+ for r:=low(regs_to_save_mm) to high(regs_to_save_mm) do
|
|
|
|
+ if regs_to_save_mm[r] in rg[R_MMREGISTER].used_in_proc then
|
|
begin
|
|
begin
|
|
{ Allocate register so the optimizer does not remove the load }
|
|
{ Allocate register so the optimizer does not remove the load }
|
|
- hreg:=newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBMMWHOLE);
|
|
|
|
|
|
+ hreg:=newreg(R_MMREGISTER,regs_to_save_mm[r],R_SUBMMWHOLE);
|
|
a_reg_alloc(list,hreg);
|
|
a_reg_alloc(list,hreg);
|
|
a_loadmm_ref_reg(list,OS_VECTOR,OS_VECTOR,href,hreg,nil);
|
|
a_loadmm_ref_reg(list,OS_VECTOR,OS_VECTOR,href,hreg,nil);
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]);
|
|
inc(href.offset,tcgsize2size[OS_VECTOR]);
|