aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2022-03-30 08:14:59 +0200
committerTristan Gingold <tgingold@free.fr>2022-03-30 08:14:59 +0200
commit79b5d8bf4597048600b62b10e9508ac326db6c19 (patch)
tree841df9adf4f6eaa31074a3f4abf388bfc841a82b
parentec6a6a6bb5bb30ca1821c9df312893ec9bd52d26 (diff)
downloadghdl-79b5d8bf4597048600b62b10e9508ac326db6c19.tar.gz
ghdl-79b5d8bf4597048600b62b10e9508ac326db6c19.tar.bz2
ghdl-79b5d8bf4597048600b62b10e9508ac326db6c19.zip
mcode: improve support of Win64 (allocate stack for home registers)
-rw-r--r--src/ortho/mcode/ortho_code-x86-abi.adb4
-rw-r--r--src/ortho/mcode/ortho_code-x86-emits.adb6
-rw-r--r--src/ortho/mcode/ortho_code-x86-insns.adb18
3 files changed, 22 insertions, 6 deletions
diff --git a/src/ortho/mcode/ortho_code-x86-abi.adb b/src/ortho/mcode/ortho_code-x86-abi.adb
index 0bba430a0..69eb8d26e 100644
--- a/src/ortho/mcode/ortho_code-x86-abi.adb
+++ b/src/ortho/mcode/ortho_code-x86-abi.adb
@@ -44,8 +44,8 @@ package body Ortho_Code.X86.Abi is
type Regs_List is array (Boolean range <>, Natural range <>) of O_Reg;
Int_Regs : constant Regs_List :=
- (False => (R_Di, R_Si, R_Dx, R_Cx, R_R8, R_R9),
- True => (R_Cx, R_Dx, R_R8, R_R9, R_None, R_None));
+ (False => (R_Di, R_Si, R_Dx, R_Cx, R_R8, R_R9), -- SysV x86-64
+ True => (R_Cx, R_Dx, R_R8, R_R9, R_None, R_None)); -- Win X64
Sse_Regs : constant Regs_List :=
(False => (R_Xmm0, R_Xmm1, R_Xmm2, R_Xmm3,
R_Xmm4, R_Xmm5, R_Xmm6, R_Xmm7),
diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb
index 48aa745e6..70b1fb584 100644
--- a/src/ortho/mcode/ortho_code-x86-emits.adb
+++ b/src/ortho/mcode/ortho_code-x86-emits.adb
@@ -1641,9 +1641,13 @@ package body Ortho_Code.X86.Emits is
Gen_8 (Opc2_Grp1_And or 2#11_000_000# or To_Reg32 (Reg));
Gen_32 (not (X86.Flags.Stack_Boundary - 1));
End_Insn;
+ -- Call chkstk if needed.
+ -- On windows x32, chkstk probes the stack and allocate stack.
+ -- On windows x64, chkstk only probes the stack.
if X86.Flags.Flag_Alloca_Call then
Gen_Call (Chkstk_Symbol);
- else
+ end if;
+ if (not X86.Flags.Flag_Alloca_Call) or X86.Flags.Win64 then
-- subl esp, reg
Start_Insn;
Gen_Rex_B (Reg, Sz_Ptr);
diff --git a/src/ortho/mcode/ortho_code-x86-insns.adb b/src/ortho/mcode/ortho_code-x86-insns.adb
index 94b16754d..0264e952a 100644
--- a/src/ortho/mcode/ortho_code-x86-insns.adb
+++ b/src/ortho/mcode/ortho_code-x86-insns.adb
@@ -1231,12 +1231,16 @@ package body Ortho_Code.X86.Insns is
use Interfaces;
Subprg : constant O_Dnode := Get_Call_Subprg (Stmt);
Push_Size : constant Uns32 := Uns32 (Get_Subprg_Stack (Subprg));
+ Push_Home : Uns32;
Reg_Res : O_Reg;
Pad : Uns32;
Res_Stmt : O_Enode;
begin
+ -- Note: Push_Offset may not be 0 if an argument contains a call.
+ -- In that case, the stack may not be aligned.
+
-- Emit Setup_Frame (to align stack).
- -- Pad the stack if necessary (this may be a nested call).
+ -- Pad the stack if necessary.
Pad := (Push_Size + Push_Offset) and Uns32 (Flags.Stack_Boundary - 1);
if Pad /= 0 then
Pad := Uns32 (Flags.Stack_Boundary) - Pad;
@@ -1256,14 +1260,22 @@ package body Ortho_Code.X86.Insns is
Clobber_Caller_Saved_Registers_32;
end if;
+ if Flags.M64 and Flags.Win64 then
+ -- Need to reserve 4*8 bytes to home registers
+ Push_Home := 4*8;
+ Gen_Stack_Adjust (Int32 (Push_Home));
+ else
+ Push_Home := 0;
+ end if;
+
-- Add the call.
Reg_Res := Get_Return_Register (Get_Expr_Mode (Stmt));
Set_Expr_Reg (Stmt, Reg_Res);
Link_Stmt (Stmt);
Res_Stmt := Stmt;
- if Push_Size + Pad /= 0 then
- Gen_Stack_Adjust (-Int32 (Push_Size + Pad));
+ if Push_Size + Push_Home + Pad /= 0 then
+ Gen_Stack_Adjust (-Int32 (Push_Size + Push_Home + Pad));
-- The stack has been restored (just after the call).
Push_Offset := Push_Offset - (Push_Size + Pad);