diff options
author | Tristan Gingold <tgingold@free.fr> | 2015-01-22 04:42:30 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2015-01-22 04:42:30 +0100 |
commit | 6caa543e9416d3a8bfc50b6f6da4b502a8069029 (patch) | |
tree | 6a9bde19612fc2b76552735109b156914eb1d902 /src/ortho/mcode/ortho_code-x86-insns.adb | |
parent | bcd53686ad09a434a81fc8ccf092ed16f454cd5c (diff) | |
download | ghdl-6caa543e9416d3a8bfc50b6f6da4b502a8069029.tar.gz ghdl-6caa543e9416d3a8bfc50b6f6da4b502a8069029.tar.bz2 ghdl-6caa543e9416d3a8bfc50b6f6da4b502a8069029.zip |
mcode x86: handle more conversions (i64 <-> u8. b2)
Diffstat (limited to 'src/ortho/mcode/ortho_code-x86-insns.adb')
-rw-r--r-- | src/ortho/mcode/ortho_code-x86-insns.adb | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/src/ortho/mcode/ortho_code-x86-insns.adb b/src/ortho/mcode/ortho_code-x86-insns.adb index 2a04e93e7..f96887436 100644 --- a/src/ortho/mcode/ortho_code-x86-insns.adb +++ b/src/ortho/mcode/ortho_code-x86-insns.adb @@ -1719,40 +1719,56 @@ package body Ortho_Code.X86.Insns is Link_Stmt (Stmt); return Stmt; when OE_Conv => + Left := Get_Expr_Operand (Stmt); declare - O_Mode : Mode_Type; -- Operand mode - R_Mode : Mode_Type; -- Result mode + -- Operand mode + O_Mode : constant Mode_Type := Get_Expr_Mode (Left); + + -- Result mode + R_Mode : constant Mode_Type := Get_Expr_Mode (Stmt); + + Reg_Op : O_Reg; begin - Left := Get_Expr_Operand (Stmt); - O_Mode := Get_Expr_Mode (Left); - R_Mode := Get_Expr_Mode (Stmt); -- Simple case: no conversion. -- FIXME: should be handled by EXPR and convert to NOP. if Get_Expr_Mode (Left) = Get_Expr_Mode (Stmt) then -- A no-op. return Gen_Insn (Left, Reg, Pnum); end if; + + -- By default, can work on reg or memory. + Reg_Op := R_Rm; + case R_Mode is when Mode_B2 => + -- To B2 case O_Mode is when Mode_U32 | Mode_I32 => -- Detect for bound. null; + when Mode_I64 => + -- Work on registers. + Reg_Op := R_Any64; when others => Error_Gen_Insn (Stmt, O_Mode); end case; when Mode_U8 => + -- To U8 case O_Mode is when Mode_U16 | Mode_U32 | Mode_I32 => -- Detect for bound. null; + when Mode_I64 => + -- Work on registers. + Reg_Op := R_Any64; when others => Error_Gen_Insn (Stmt, O_Mode); end case; when Mode_U32 => + -- To U32 case O_Mode is when Mode_I32 => -- Detect for bound. @@ -1766,6 +1782,7 @@ package body Ortho_Code.X86.Insns is Error_Gen_Insn (Stmt, O_Mode); end case; when Mode_I32 => + -- To I32 case O_Mode is when Mode_U8 | Mode_I8 @@ -1802,9 +1819,12 @@ package body Ortho_Code.X86.Insns is Error_Gen_Insn (Stmt, O_Mode); end case; when Mode_I64 => + -- To I64 case O_Mode is when Mode_I32 - | Mode_U32 => + | Mode_U32 + | Mode_U8 + | Mode_B2 => -- Zero or Sign extend. Num := Get_Insn_Num; Left := Gen_Insn (Left, R_Ax, Num); @@ -1830,6 +1850,7 @@ package body Ortho_Code.X86.Insns is Error_Gen_Insn (Stmt, O_Mode); end case; when Mode_F64 => + -- To F64 case O_Mode is when Mode_I32 | Mode_I64 => @@ -1840,7 +1861,7 @@ package body Ortho_Code.X86.Insns is when others => Error_Gen_Insn (Stmt, O_Mode); end case; - Left := Gen_Insn (Left, R_Rm, Pnum); + Left := Gen_Insn (Left, Reg_Op, Pnum); Set_Expr_Operand (Stmt, Left); case Reg is when R_Irm |