aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-02-29 17:38:04 +0100
committerTristan Gingold <tgingold@free.fr>2020-02-29 17:38:04 +0100
commitaaa25b2ed917f4c90c1011239142987299440961 (patch)
tree9219c3c6048346b6e6bc782653c3d49ad60d8b3a
parent62a8c4ba331132b2e0be886673d769e2f742834f (diff)
downloadghdl-aaa25b2ed917f4c90c1011239142987299440961.tar.gz
ghdl-aaa25b2ed917f4c90c1011239142987299440961.tar.bz2
ghdl-aaa25b2ed917f4c90c1011239142987299440961.zip
synth: handle more physical operators. Fix #1146
-rw-r--r--src/synth/synth-expr.adb13
-rw-r--r--src/synth/synth-oper.adb20
-rw-r--r--src/synth/synth-oper.ads2
-rw-r--r--src/synth/synth-static_oper.adb66
4 files changed, 80 insertions, 21 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index c1fe74d81..9d71145b6 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -1912,11 +1912,14 @@ package body Synth.Expr is
declare
Imp : constant Node := Get_Implementation (Expr);
begin
- if Get_Implicit_Definition (Imp) /= Iir_Predefined_None then
- return Synth_Predefined_Function_Call (Syn_Inst, Expr);
- else
- return Synth_User_Function_Call (Syn_Inst, Expr);
- end if;
+ case Get_Implicit_Definition (Imp) is
+ when Iir_Predefined_Pure_Functions =>
+ return Synth_Operator_Function_Call (Syn_Inst, Expr);
+ when Iir_Predefined_None =>
+ return Synth_User_Function_Call (Syn_Inst, Expr);
+ when others =>
+ return Synth_Predefined_Function_Call (Syn_Inst, Expr);
+ end case;
end;
when Iir_Kind_Aggregate =>
return Synth_Aggregate (Syn_Inst, Expr, Expr_Type);
diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb
index a185eef17..5146390fe 100644
--- a/src/synth/synth-oper.adb
+++ b/src/synth/synth-oper.adb
@@ -1463,4 +1463,24 @@ package body Synth.Oper is
return Res;
end Synth_Predefined_Function_Call;
+
+ function Synth_Operator_Function_Call
+ (Syn_Inst : Synth_Instance_Acc; Expr : Node) return Value_Acc
+ is
+ Imp : constant Node := Get_Implementation (Expr);
+ Assoc : Node;
+ Inter : Node;
+ Op1, Op2 : Node;
+ begin
+ Assoc := Get_Parameter_Association_Chain (Expr);
+ Inter := Get_Interface_Declaration_Chain (Imp);
+
+ Op1 := Get_Actual (Assoc);
+ if Get_Chain (Inter) = Null_Node then
+ return Synth_Monadic_Operation (Syn_Inst, Imp, Op1, Expr);
+ else
+ Op2 := Get_Actual (Get_Chain (Assoc));
+ return Synth_Dyadic_Operation (Syn_Inst, Imp, Op1, Op2, Expr);
+ end if;
+ end Synth_Operator_Function_Call;
end Synth.Oper;
diff --git a/src/synth/synth-oper.ads b/src/synth/synth-oper.ads
index 43ed42d21..1bf30562b 100644
--- a/src/synth/synth-oper.ads
+++ b/src/synth/synth-oper.ads
@@ -25,6 +25,8 @@ with Vhdl.Nodes; use Vhdl.Nodes;
package Synth.Oper is
function Synth_Predefined_Function_Call
(Syn_Inst : Synth_Instance_Acc; Expr : Node) return Value_Acc;
+ function Synth_Operator_Function_Call
+ (Syn_Inst : Synth_Instance_Acc; Expr : Node) return Value_Acc;
function Synth_Dyadic_Operation (Syn_Inst : Synth_Instance_Acc;
Imp : Node;
diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb
index a76f9b5e0..dbdb6c784 100644
--- a/src/synth/synth-static_oper.adb
+++ b/src/synth/synth-static_oper.adb
@@ -326,19 +326,25 @@ package body Synth.Static_Oper is
return Create_Value_Discrete
(Boolean'Pos (Left.Scal /= Right.Scal), Boolean_Type);
- when Iir_Predefined_Integer_Plus =>
+ when Iir_Predefined_Integer_Plus
+ | Iir_Predefined_Physical_Plus =>
return Create_Value_Discrete
(Get_Static_Discrete (Left) + Get_Static_Discrete (Right),
Res_Typ);
- when Iir_Predefined_Integer_Minus =>
+ when Iir_Predefined_Integer_Minus
+ | Iir_Predefined_Physical_Minus =>
return Create_Value_Discrete
(Get_Static_Discrete (Left) - Get_Static_Discrete (Right),
Res_Typ);
- when Iir_Predefined_Integer_Mul =>
+ when Iir_Predefined_Integer_Mul
+ | Iir_Predefined_Physical_Integer_Mul
+ | Iir_Predefined_Integer_Physical_Mul =>
return Create_Value_Discrete
(Get_Static_Discrete (Left) * Get_Static_Discrete (Right),
Res_Typ);
- when Iir_Predefined_Integer_Div =>
+ when Iir_Predefined_Integer_Div
+ | Iir_Predefined_Physical_Physical_Div
+ | Iir_Predefined_Physical_Integer_Div =>
return Create_Value_Discrete
(Get_Static_Discrete (Left) / Get_Static_Discrete (Right),
Res_Typ);
@@ -352,30 +358,53 @@ package body Synth.Static_Oper is
when Iir_Predefined_Integer_Exp =>
return Create_Value_Discrete
(Left.Scal ** Natural (Right.Scal), Res_Typ);
- when Iir_Predefined_Integer_Less_Equal =>
+ when Iir_Predefined_Physical_Minimum =>
+ return Create_Value_Discrete
+ (Int64'Min (Get_Static_Discrete (Left),
+ Get_Static_Discrete (Right)),
+ Res_Typ);
+ when Iir_Predefined_Physical_Maximum =>
+ return Create_Value_Discrete
+ (Int64'Max (Get_Static_Discrete (Left),
+ Get_Static_Discrete (Right)),
+ Res_Typ);
+ when Iir_Predefined_Integer_Less_Equal
+ | Iir_Predefined_Physical_Less_Equal =>
return Create_Value_Discrete
(Boolean'Pos (Left.Scal <= Right.Scal), Boolean_Type);
- when Iir_Predefined_Integer_Less =>
+ when Iir_Predefined_Integer_Less
+ | Iir_Predefined_Physical_Less =>
return Create_Value_Discrete
(Boolean'Pos (Left.Scal < Right.Scal), Boolean_Type);
- when Iir_Predefined_Integer_Greater_Equal =>
+ when Iir_Predefined_Integer_Greater_Equal
+ | Iir_Predefined_Physical_Greater_Equal =>
return Create_Value_Discrete
(Boolean'Pos (Left.Scal >= Right.Scal), Boolean_Type);
- when Iir_Predefined_Integer_Greater =>
+ when Iir_Predefined_Integer_Greater
+ | Iir_Predefined_Physical_Greater =>
return Create_Value_Discrete
(Boolean'Pos (Left.Scal > Right.Scal), Boolean_Type);
- when Iir_Predefined_Integer_Equality =>
+ when Iir_Predefined_Integer_Equality
+ | Iir_Predefined_Physical_Equality =>
return Create_Value_Discrete
(Boolean'Pos (Get_Static_Discrete (Left)
= Get_Static_Discrete (Right)), Boolean_Type);
- when Iir_Predefined_Integer_Inequality =>
+ when Iir_Predefined_Integer_Inequality
+ | Iir_Predefined_Physical_Inequality =>
return Create_Value_Discrete
(Boolean'Pos (Get_Static_Discrete (Left)
- /= Get_Static_Discrete (Right)), Boolean_Type);
- when Iir_Predefined_Physical_Physical_Div
- | Iir_Predefined_Physical_Integer_Div =>
+ /= Get_Static_Discrete (Right)),
+ Boolean_Type);
+
+ when Iir_Predefined_Physical_Real_Mul =>
+ return Create_Value_Discrete
+ (Int64 (Fp64 (Left.Scal) * Right.Fp), Res_Typ);
+ when Iir_Predefined_Real_Physical_Mul =>
return Create_Value_Discrete
- (Left.Scal / Right.Scal, Res_Typ);
+ (Int64 (Left.Fp * Fp64 (Right.Scal)), Res_Typ);
+ when Iir_Predefined_Physical_Real_Div =>
+ return Create_Value_Discrete
+ (Int64 (Fp64 (Left.Scal) / Right.Fp), Res_Typ);
when Iir_Predefined_Floating_Less =>
return Create_Value_Discrete
@@ -607,10 +636,15 @@ package body Synth.Static_Oper is
| Iir_Predefined_Bit_Not =>
return Create_Value_Discrete (1 - Operand.Scal, Oper_Typ);
- when Iir_Predefined_Integer_Negation =>
+ when Iir_Predefined_Integer_Negation
+ | Iir_Predefined_Physical_Negation =>
return Create_Value_Discrete (-Operand.Scal, Oper_Typ);
- when Iir_Predefined_Integer_Absolute =>
+ when Iir_Predefined_Integer_Absolute
+ | Iir_Predefined_Physical_Absolute =>
return Create_Value_Discrete (abs Operand.Scal, Oper_Typ);
+ when Iir_Predefined_Integer_Identity
+ | Iir_Predefined_Physical_Identity =>
+ return Operand;
when Iir_Predefined_Floating_Negation =>
return Create_Value_Float (-Operand.Fp, Oper_Typ);