aboutsummaryrefslogtreecommitdiffstats
path: root/src/ortho/mcode/ortho_code-x86-insns.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2015-01-22 04:42:30 +0100
committerTristan Gingold <tgingold@free.fr>2015-01-22 04:42:30 +0100
commit6caa543e9416d3a8bfc50b6f6da4b502a8069029 (patch)
tree6a9bde19612fc2b76552735109b156914eb1d902 /src/ortho/mcode/ortho_code-x86-insns.adb
parentbcd53686ad09a434a81fc8ccf092ed16f454cd5c (diff)
downloadghdl-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.adb35
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