aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-11-06 20:45:38 +0100
committerTristan Gingold <tgingold@free.fr>2019-11-06 20:45:38 +0100
commite4279a1ee9d3c7d4efdbd0c195a122a9100e7027 (patch)
tree102678472dd1a53f6e96a11227f0bdf0e2af9e1b
parent96bbb16c6ac6960baeabcf8b085ea9b4a3fed803 (diff)
downloadghdl-e4279a1ee9d3c7d4efdbd0c195a122a9100e7027.tar.gz
ghdl-e4279a1ee9d3c7d4efdbd0c195a122a9100e7027.tar.bz2
ghdl-e4279a1ee9d3c7d4efdbd0c195a122a9100e7027.zip
synth: handle short-circuit and. Fix #1005
-rw-r--r--src/synth/synth-expr.adb47
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