diff options
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-abi.adb | 4 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-emits.adb | 6 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-insns.adb | 18 |
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); |