aboutsummaryrefslogtreecommitdiffstats
path: root/src/ortho/mcode/ortho_code-x86-emits.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2017-06-28 07:52:12 +0200
committerTristan Gingold <tgingold@free.fr>2017-06-28 07:52:12 +0200
commit03634c4038ebca7a43d385aea66a09d73504c769 (patch)
treec843127e4194bfb7699fbfe1903f430ccb803674 /src/ortho/mcode/ortho_code-x86-emits.adb
parentb7d2a39f80e4dc06958b8e399a879b163e4eb499 (diff)
downloadghdl-03634c4038ebca7a43d385aea66a09d73504c769.tar.gz
ghdl-03634c4038ebca7a43d385aea66a09d73504c769.tar.bz2
ghdl-03634c4038ebca7a43d385aea66a09d73504c769.zip
ortho/mcode: preliminary work to support win64.
Diffstat (limited to 'src/ortho/mcode/ortho_code-x86-emits.adb')
-rw-r--r--src/ortho/mcode/ortho_code-x86-emits.adb64
1 files changed, 37 insertions, 27 deletions
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;