From 03634c4038ebca7a43d385aea66a09d73504c769 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 28 Jun 2017 07:52:12 +0200 Subject: ortho/mcode: preliminary work to support win64. --- src/ortho/mcode/ortho_code-x86-emits.adb | 64 ++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 27 deletions(-) (limited to 'src/ortho/mcode/ortho_code-x86-emits.adb') diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb index 4753aab85..03c4e63a8 100644 --- a/src/ortho/mcode/ortho_code-x86-emits.adb +++ b/src/ortho/mcode/ortho_code-x86-emits.adb @@ -2821,35 +2821,31 @@ package body Ortho_Code.X86.Emits is end case; end Emit_Insn; - function Get_Preserved_Regs return O_Reg_Array is + function Get_Preserved_Regs return O_Reg_Bitmap is begin if Flags.M64 then - return Preserved_Regs_64; + if Flags.Win64 then + return Preserved_Regs_Win64; + else + return Preserved_Regs_Lin64; + end if; else return Preserved_Regs_32; end if; end Get_Preserved_Regs; -- List of registers preserved accross calls. - Preserved_Regs : constant O_Reg_Array := Get_Preserved_Regs; + Preserved_Regs : constant O_Reg_Bitmap := Get_Preserved_Regs; - procedure Push_Reg_If_Used (Reg : Regs_R64) - is - use Ortho_Code.X86.Insns; + procedure Push_Reg (Reg : Regs_R64) is begin - if Reg_Used (Reg) then - Gen_Push_Pop_Reg (Opc_Push_Reg, Reg, Sz_Ptr); - end if; - end Push_Reg_If_Used; + Gen_Push_Pop_Reg (Opc_Push_Reg, Reg, Sz_Ptr); + end Push_Reg; - procedure Pop_Reg_If_Used (Reg : Regs_R64) - is - use Ortho_Code.X86.Insns; + procedure Pop_Reg (Reg : Regs_R64) is begin - if Reg_Used (Reg) then - Gen_Push_Pop_Reg (Opc_Pop_Reg, Reg, Sz_Ptr); - end if; - end Pop_Reg_If_Used; + Gen_Push_Pop_Reg (Opc_Pop_Reg, Reg, Sz_Ptr); + end Pop_Reg; procedure Emit_Prologue (Subprg : Subprogram_Data_Acc) is @@ -2868,6 +2864,7 @@ package body Ortho_Code.X86.Emits is Set_Current_Section (Sect_Text); Gen_Pow_Align (2); + -- Set symbol. Subprg_Decl := Subprg.D_Decl; Sym := Get_Decl_Symbol (Subprg_Decl); case Get_Decl_Storage (Subprg_Decl) is @@ -2883,8 +2880,8 @@ package body Ortho_Code.X86.Emits is -- Return address and saved frame pointer are preserved. Saved_Regs_Size := 2; - for I in Preserved_Regs'Range loop - if Reg_Used (Preserved_Regs (I)) then + for R in Preserved_Regs'Range loop + if Preserved_Regs (R) and Reg_Used (R) then Saved_Regs_Size := Saved_Regs_Size + 1; end if; end loop; @@ -2895,6 +2892,8 @@ package body Ortho_Code.X86.Emits is end if; -- Compute frame size. + -- Saved_Regs_Size must be added and substracted as the stack boundary + -- can be larger than a reg size. Frame_Size := Unsigned_32 (Subprg.Stack_Max) + Saved_Regs_Size; -- Align. Frame_Size := (Frame_Size + X86.Flags.Stack_Boundary - 1) @@ -2904,7 +2903,7 @@ package body Ortho_Code.X86.Emits is -- Emit prolog. -- push %ebp / push %rbp - Gen_Push_Pop_Reg (Opc_Push_Reg, R_Bp, Sz_Ptr); + Push_Reg (R_Bp); -- movl %esp, %ebp / movl %rsp, %rbp Start_Insn; Gen_Rex (16#48#); @@ -2912,7 +2911,7 @@ package body Ortho_Code.X86.Emits is Gen_8 (2#11_100_101#); End_Insn; - -- Save int registers. + -- Save int arguments (only on x86-64). Has_Fp_Inter := False; if Flags.M64 then declare @@ -2923,9 +2922,13 @@ package body Ortho_Code.X86.Emits is while Inter /= O_Dnode_Null loop R := Get_Decl_Reg (Inter); if R in Regs_R64 then - Gen_Push_Pop_Reg (Opc_Push_Reg, R, Sz_Ptr); + Push_Reg (R); + -- Space for arguments was already counted in frame size. + -- As the space is allocated by the push, don't allocate it + -- later. Frame_Size := Frame_Size - 8; elsif R in Regs_Xmm then + -- Need to save Xmm registers, but later. Has_Fp_Inter := True; else pragma Assert (R = R_None); @@ -2956,6 +2959,7 @@ package body Ortho_Code.X86.Emits is end if; end if; + -- Save XMM arguments. if Flags.M64 and Has_Fp_Inter then declare Inter : O_Dnode; @@ -2971,6 +2975,7 @@ package body Ortho_Code.X86.Emits is Gen_SSE_Opc (Opc_Movsd_M64_Xmm); Gen_Mod_Rm_Reg; End_Insn; + -- No need to adjust frame_size, it was already allocated. end if; Inter := Get_Interface_Chain (Inter); end loop; @@ -2981,9 +2986,11 @@ package body Ortho_Code.X86.Emits is Gen_Call (Mcount_Symbol); end if; - -- Save registers. - for I in Preserved_Regs'Range loop - Push_Reg_If_Used (Preserved_Regs (I)); + -- Save preserved registers that are used in the function. + for R in Preserved_Regs'Range loop + if Preserved_Regs (R) and Reg_Used (R) then + Push_Reg (R); + end if; end loop; end Emit_Prologue; @@ -2992,12 +2999,15 @@ package body Ortho_Code.X86.Emits is use Ortho_Code.Decls; use Ortho_Code.Types; use Ortho_Code.Flags; + use Ortho_Code.X86.Insns; Decl : O_Dnode; Mode : Mode_Type; begin -- Restore registers. - for I in reverse Preserved_Regs'Range loop - Pop_Reg_If_Used (Preserved_Regs (I)); + for R in reverse Preserved_Regs'Range loop + if Preserved_Regs (R) and Reg_Used (R) then + Pop_Reg (R); + end if; end loop; Decl := Subprg.D_Decl; -- cgit v1.2.3