diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-11-06 20:45:38 +0100 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-11-06 20:45:38 +0100 |
commit | e4279a1ee9d3c7d4efdbd0c195a122a9100e7027 (patch) | |
tree | 102678472dd1a53f6e96a11227f0bdf0e2af9e1b | |
parent | 96bbb16c6ac6960baeabcf8b085ea9b4a3fed803 (diff) | |
download | ghdl-e4279a1ee9d3c7d4efdbd0c195a122a9100e7027.tar.gz ghdl-e4279a1ee9d3c7d4efdbd0c195a122a9100e7027.tar.bz2 ghdl-e4279a1ee9d3c7d4efdbd0c195a122a9100e7027.zip |
synth: handle short-circuit and. Fix #1005
-rw-r--r-- | src/synth/synth-expr.adb | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index c580fb613..3c51ca177 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1535,6 +1535,30 @@ package body Synth.Expr is return Res; end Synth_String_Literal; + function Synth_Short_Circuit_And (Syn_Inst : Synth_Instance_Acc; + Left_Expr : Node; + Right_Expr : Node; + Typ : Type_Acc; + Expr : Node) return Value_Acc + is + Left : Value_Acc; + Right : Value_Acc; + N : Net; + begin + Left := Synth_Expression_With_Type (Syn_Inst, Left_Expr, Typ); + if Is_Const_Val (Left) and then Get_Const_Discrete (Left) = 0 then + return Create_Value_Discrete (0, Boolean_Type); + end if; + Strip_Const (Left); + Right := Synth_Expression_With_Type (Syn_Inst, Right_Expr, Typ); + Strip_Const (Right); + + N := Build_Dyadic (Build_Context, Id_And, + Get_Net (Left), Get_Net (Right)); + Set_Location (N, Expr); + return Create_Value_Net (N, Boolean_Type); + end Synth_Short_Circuit_And; + function Synth_Expression_With_Type (Syn_Inst : Synth_Instance_Acc; Expr : Node; Expr_Type : Type_Acc) return Value_Acc @@ -1559,15 +1583,20 @@ package body Synth.Expr is end if; -- FIXME: short-circuit operators ? - if Def in Iir_Predefined_Implicit - or else Def in Iir_Predefined_IEEE_Explicit - then - return Synth_Dyadic_Operation - (Syn_Inst, Imp, Get_Left (Expr), Get_Right (Expr), Expr); - else - Error_Unknown_Operator (Imp, Expr); - raise Internal_Error; - end if; + case Def is + when Iir_Predefined_Boolean_And => + return Synth_Short_Circuit_And + (Syn_Inst, Get_Left (Expr), Get_Right (Expr), + Boolean_Type, Expr); + when Iir_Predefined_Bit_And => + return Synth_Short_Circuit_And + (Syn_Inst, Get_Left (Expr), Get_Right (Expr), + Bit_Type, Expr); + when others => + return Synth_Dyadic_Operation + (Syn_Inst, Imp, + Get_Left (Expr), Get_Right (Expr), Expr); + end case; end; when Iir_Kinds_Monadic_Operator => declare |