diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-abi.ads | 2 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-emits.adb | 15 | ||||
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-insns.adb | 21 |
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 c7dc49c..6a07127 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 46a6423..8e0b8f4 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 7560abc..d57938a 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 => |