summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ortho/mcode/ortho_code-x86-emits.adb21
-rw-r--r--src/ortho/mcode/ortho_code-x86-insns.adb5
2 files changed, 19 insertions, 7 deletions
diff --git a/src/ortho/mcode/ortho_code-x86-emits.adb b/src/ortho/mcode/ortho_code-x86-emits.adb
index ad1ef55..27f78ef 100644
--- a/src/ortho/mcode/ortho_code-x86-emits.adb
+++ b/src/ortho/mcode/ortho_code-x86-emits.adb
@@ -467,6 +467,15 @@ package body Ortho_Code.X86.Emits is
End_Insn;
end Gen_Cdq;
+ procedure Gen_Clear_Edx is
+ begin
+ -- Xorl edx, edx
+ Start_Insn;
+ Gen_B8 (2#0011_0001#);
+ Gen_B8 (2#11_010_010#);
+ End_Insn;
+ end Gen_Clear_Edx;
+
procedure Gen_Mono_Op (Op : Byte; Val : O_Enode; Sz : Insn_Size) is
begin
Start_Insn;
@@ -1131,6 +1140,12 @@ package body Ortho_Code.X86.Emits is
end if;
Emit_Tst (Reg_Res, Sz_32l);
Gen_Ov_Check (R_Sge);
+ when Mode_I64 =>
+ if Reg_Res /= R_Edx_Eax or Reg_Op /= R_Ax then
+ raise Program_Error;
+ end if;
+ -- Clear edx.
+ Gen_Clear_Edx;
when Mode_U8
| Mode_B2 =>
if Reg_Res not in Regs_R32 then
@@ -1562,11 +1577,7 @@ package body Ortho_Code.X86.Emits is
| OE_Div_Ov =>
case Mode is
when Mode_U32 =>
- -- Xorl edx, edx
- Start_Insn;
- Gen_B8 (2#0011_0001#);
- Gen_B8 (2#11_010_010#);
- End_Insn;
+ Gen_Clear_Edx;
Gen_Mono_Op (2#110_000#, Get_Expr_Right (Stmt), Sz_32l);
when Mode_I32 =>
if Kind = OE_Mod then
diff --git a/src/ortho/mcode/ortho_code-x86-insns.adb b/src/ortho/mcode/ortho_code-x86-insns.adb
index c218a9a..e600f47 100644
--- a/src/ortho/mcode/ortho_code-x86-insns.adb
+++ b/src/ortho/mcode/ortho_code-x86-insns.adb
@@ -1798,8 +1798,9 @@ package body Ortho_Code.X86.Insns is
end case;
when Mode_I64 =>
case O_Mode is
- when Mode_I32 =>
- -- Sign extend.
+ when Mode_I32
+ | Mode_U32 =>
+ -- Zero or Sign extend.
Num := Get_Insn_Num;
Left := Gen_Insn (Left, R_Ax, Num);
Set_Expr_Operand (Stmt, Left);