diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-06-12 18:43:15 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-06-12 18:43:15 +0200 |
commit | 43d088c8efbc5882b0d6363885e6ac4cf17a2246 (patch) | |
tree | 072141993c66f43d2f1e742b29536077ee62970f | |
parent | 23bd5955da7d80e56e4bc9d1f756d13a1753d6e7 (diff) | |
download | ghdl-43d088c8efbc5882b0d6363885e6ac4cf17a2246.tar.gz ghdl-43d088c8efbc5882b0d6363885e6ac4cf17a2246.tar.bz2 ghdl-43d088c8efbc5882b0d6363885e6ac4cf17a2246.zip |
synth-expr: handle choice_by_expression in aggregates.
-rw-r--r-- | src/synth/synth-expr.adb | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 5abb5ffa2..f49881872 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -179,6 +179,13 @@ package body Synth.Expr is Stride : Iir_Index32) is Bound : constant Iir_Value_Literal_Acc := Res.Bounds.D (Dim); + Aggr_Type : constant Node := Get_Type (Aggr); + El_Type : constant Node := Get_Element_Subtype (Aggr_Type); + Idx_Type : constant Node := + Get_Index_Type (Aggr_Type, Natural (Dim - 1)); + type Boolean_Array is array (Iir_Index32 range <>) of Boolean; + pragma Pack (Boolean_Array); + Is_Set : Boolean_Array (0 .. Bound.Length - 1); Value : Iir; Assoc : Iir; Pos : Iir_Index32; @@ -188,9 +195,10 @@ package body Synth.Expr is Val : Value_Acc; begin if Dim = Res.Bounds.Nbr_Dims then - Val := Synth_Expression_With_Type - (Syn_Inst, Value, Get_Element_Subtype (Get_Type (Aggr))); + Val := Synth_Expression_With_Type (Syn_Inst, Value, El_Type); Res.Arr.V (Orig + Stride * Pos) := Val; + pragma Assert (not Is_Set (Pos)); + Is_Set (Pos) := True; else Error_Msg_Synth (+Assoc, "multi-dim aggregate not handled"); end if; @@ -198,6 +206,7 @@ package body Synth.Expr is begin Assoc := Get_Association_Choices_Chain (Aggr); Pos := 0; + Is_Set := (others => False); while Is_Valid (Assoc) loop Value := Get_Associated_Expr (Assoc); loop @@ -211,9 +220,27 @@ package body Synth.Expr is Pos := Pos + 1; when Iir_Kind_Choice_By_Others => while Pos < Bound.Length loop - Set_Elem (Pos); + if not Is_Set (Pos) then + Set_Elem (Pos); + end if; Pos := Pos + 1; end loop; + when Iir_Kind_Choice_By_Expression => + declare + Ch : constant Node := Get_Choice_Expression (Assoc); + Idx : Value_Acc; + begin + Idx := Synth_Expression_With_Type + (Syn_Inst, Ch, Idx_Type); + if not Is_Const (Idx) then + Error_Msg_Synth (+Ch, "choice is not static"); + else + Set_Elem (Simul.Execution.Get_Index_Offset + (Idx.Lit, Bound, Ch)); + end if; + end; + when Iir_Kind_Choice_By_Range => + raise Internal_Error; when others => Error_Msg_Synth (+Assoc, "unhandled association form"); |