aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ortho/mcode/ortho_code-x86-abi.ads2
-rw-r--r--src/ortho/mcode/ortho_code-x86-emits.adb15
-rw-r--r--src/ortho/mcode/ortho_code-x86-insns.adb21
3 files changed, 28 insertions, 10 deletions
diff --git a/src/ortho/mcode/ortho_code-x86-abi.ads b/src/ortho/mcode/ortho_code-x86-abi.ads
index c7dc49cc9..6a07127e2 100644
--- a/src/ortho/mcode/ortho_code-x86-abi.ads
+++ b/src/ortho/mcode/ortho_code-x86-abi.ads
@@ -40,7 +40,7 @@ package Ortho_Code.X86.Abi is
-- If True, use SSE/SSE2 instructions instead of FPU one. The code is
-- still compliant with the ABI (ie FP values are returned in st0).
-- TODO: this is still work in progress.
- Flag_Sse2 : constant Boolean := False;
+ Flag_Sse2 : constant Boolean := True;
-- Procedures to layout a subprogram declaration.
procedure Start_Subprogram (Subprg : O_Dnode; Abi : out O_Abi_Subprg);
diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb
index 46a6423e6..8e0b8f447 100644
--- a/src/ortho/mcode/ortho_code-x86-emits.adb
+++ b/src/ortho/mcode/ortho_code-x86-emits.adb
@@ -1638,9 +1638,19 @@ package body Ortho_Code.X86.Emits is
-- Convert FP to xxx.
procedure Gen_Conv_Fp (Stmt : O_Enode)
is
+ Mode : constant Mode_Type := Get_Expr_Mode (Stmt);
Reg : constant O_Reg := Get_Expr_Reg (Stmt);
Reg_Op : constant O_Reg := Get_Expr_Reg (Get_Expr_Operand (Stmt));
begin
+ if Mode = Mode_I32 and then Reg_Op in Regs_Xmm then
+ -- cvtsd2si
+ Init_Modrm_Reg (Reg_Op, Sz_32l);
+ Gen_SSE_Rep_Opc (Mode_F64, 16#2d#);
+ Gen_Mod_Rm (To_Reg32 (Reg) * 8);
+ End_Insn;
+ return;
+ end if;
+
Init_Modrm_Offset
(R_Bp, -Int32 (Cur_Subprg.Target.Fp_Slot), Sz_32l);
@@ -1657,7 +1667,7 @@ package body Ortho_Code.X86.Emits is
End_Insn;
end if;
- case Get_Expr_Mode (Stmt) is
+ case Mode is
when Mode_I32 =>
-- fistpl slot(%ebp)
Start_Insn;
@@ -1946,8 +1956,7 @@ package body Ortho_Code.X86.Emits is
| Mode_F64 =>
-- No Mod or Rem for fp types.
pragma Assert (Kind = OE_Div_Ov);
- Gen_Emit_Fp_Or_Xmm_Op
- (Stmt, 2#111_000#, 2#110_000#, 16#5e#);
+ Gen_Emit_Fp_Or_Xmm_Op (Stmt, 2#110_000#, 2#110_000#, 16#5e#);
when others =>
Error_Emit ("emit_insn: mod_ov", Stmt);
end case;
diff --git a/src/ortho/mcode/ortho_code-x86-insns.adb b/src/ortho/mcode/ortho_code-x86-insns.adb
index 7560abc00..d57938a1d 100644
--- a/src/ortho/mcode/ortho_code-x86-insns.adb
+++ b/src/ortho/mcode/ortho_code-x86-insns.adb
@@ -1658,16 +1658,25 @@ package body Ortho_Code.X86.Insns is
return Insert_Intrinsic (Stmt, R_Edx_Eax, Pnum);
when Mode_F32
| Mode_F64 =>
- Reg_Res := Get_Reg_Any (Mode);
+ if Abi.Flag_Sse2 then
+ if Reg in Regs_Xmm then
+ Reg_Res := Reg;
+ else
+ Reg_Res := R_Any_Xmm;
+ end if;
+ else
+ Reg_Res := R_St0;
+ end if;
+ Right := Gen_Insn (Right, R_Irm, Num);
Left := Gen_Insn (Left, Reg_Res, Num);
- Right := Gen_Insn (Right, R_Rm, Num);
+ Right := Reload (Right, R_Irm, Num);
Left := Reload (Left, Reg_Res, Num);
- Set_Expr_Left (Stmt, Left);
+ Reg_Res := Get_Expr_Reg (Left);
Set_Expr_Right (Stmt, Right);
+ Set_Expr_Left (Stmt, Left);
+ Set_Expr_Reg (Stmt, Reg_Res);
+ Renum_Reg (Reg_Res, Stmt, Pnum);
Free_Insn_Regs (Right);
- Free_Insn_Regs (Left);
- Reg_Res := Get_Expr_Reg (Left);
- Set_Expr_Reg (Stmt, Alloc_Reg (Reg_Res, Stmt, Pnum));
Link_Stmt (Stmt);
return Stmt;
when others =>