diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-02-29 17:38:04 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-02-29 17:38:04 +0100 |
commit | aaa25b2ed917f4c90c1011239142987299440961 (patch) | |
tree | 9219c3c6048346b6e6bc782653c3d49ad60d8b3a | |
parent | 62a8c4ba331132b2e0be886673d769e2f742834f (diff) | |
download | ghdl-aaa25b2ed917f4c90c1011239142987299440961.tar.gz ghdl-aaa25b2ed917f4c90c1011239142987299440961.tar.bz2 ghdl-aaa25b2ed917f4c90c1011239142987299440961.zip |
synth: handle more physical operators. Fix #1146
-rw-r--r-- | src/synth/synth-expr.adb | 13 | ||||
-rw-r--r-- | src/synth/synth-oper.adb | 20 | ||||
-rw-r--r-- | src/synth/synth-oper.ads | 2 | ||||
-rw-r--r-- | src/synth/synth-static_oper.adb | 66 |
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); |