aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-expr.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-expr.adb')
-rw-r--r--src/synth/synth-expr.adb86
1 files changed, 84 insertions, 2 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index 063257008..7bdad0672 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -257,6 +257,7 @@ package body Synth.Expr is
Idx_Type : constant Node := Get_Index_Type (Aggr_Type, Dim);
type Boolean_Array is array (Uns32 range <>) of Boolean;
pragma Pack (Boolean_Array);
+ -- FIXME: test Res.Arr.V (I) instead.
Is_Set : Boolean_Array (0 .. Bound.Len - 1);
Value : Node;
Assoc : Node;
@@ -336,6 +337,55 @@ package body Synth.Expr is
end loop;
end Fill_Array_Aggregate;
+ procedure Fill_Record_Aggregate (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Res : Value_Acc)
+ is
+ El_List : constant Node_Flist :=
+ Get_Elements_Declaration_List (Get_Type (Aggr));
+ Value : Node;
+ Assoc : Node;
+ Pos : Natural;
+
+ procedure Set_Elem (Pos : Natural)
+ is
+ Val : Value_Acc;
+ begin
+ Val := Synth_Expression_With_Type
+ (Syn_Inst, Value, Get_Type (Get_Nth_Element (El_List, Pos)));
+ Res.Rec.V (Iir_Index32 (Pos + 1)) := Val;
+ end Set_Elem;
+ begin
+ Assoc := Get_Association_Choices_Chain (Aggr);
+ Pos := 0;
+ Res.Rec.V := (others => null);
+ while Is_Valid (Assoc) loop
+ Value := Get_Associated_Expr (Assoc);
+ loop
+ case Get_Kind (Assoc) is
+ when Iir_Kind_Choice_By_None =>
+ Set_Elem (Pos);
+ Pos := Pos + 1;
+ when Iir_Kind_Choice_By_Others =>
+ for I in Res.Rec.V'Range loop
+ if Res.Rec.V (I) = null then
+ Set_Elem (Natural (I - 1));
+ end if;
+ end loop;
+ when Iir_Kind_Choice_By_Name =>
+ Pos := Natural (Get_Element_Position (Get_Name (Assoc)));
+ Set_Elem (Pos);
+ when others =>
+ Error_Msg_Synth
+ (+Assoc, "unhandled association form");
+ end case;
+ Assoc := Get_Chain (Assoc);
+ exit when Is_Null (Assoc);
+ exit when not Get_Same_Alternative_Flag (Assoc);
+ end loop;
+ end loop;
+ end Fill_Record_Aggregate;
+
procedure Concat_Array (Arr : in out Net_Array)
is
Last : Int32;
@@ -635,13 +685,29 @@ package body Synth.Expr is
Fill_Array_Aggregate (Syn_Inst, Aggr, Res, 0);
- if Is_Vector_Type (Aggr_Type) then
+ if False and Is_Vector_Type (Aggr_Type) then
Res := Vectorize_Array (Res, Get_Element_Subtype (Aggr_Type));
end if;
return Res;
end Synth_Aggregate_Array;
+ function Synth_Aggregate_Record (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Aggr_Type : Node) return Value_Acc
+ is
+ Res_Type : Type_Acc;
+ Res : Value_Acc;
+ begin
+ -- Allocate the result.
+ Res_Type := Get_Value_Type (Syn_Inst, Aggr_Type);
+ Res := Create_Value_Record (Res_Type);
+
+ Fill_Record_Aggregate (Syn_Inst, Aggr, Res);
+
+ return Res;
+ end Synth_Aggregate_Record;
+
-- Aggr_Type is the type from the context.
function Synth_Aggregate (Syn_Inst : Synth_Instance_Acc;
Aggr : Node;
@@ -654,7 +720,7 @@ package body Synth.Expr is
return Synth_Aggregate_Array (Syn_Inst, Aggr, Aggr_Type);
when Iir_Kind_Record_Type_Definition
| Iir_Kind_Record_Subtype_Definition =>
- raise Internal_Error;
+ return Synth_Aggregate_Record (Syn_Inst, Aggr, Aggr_Type);
when others =>
Error_Kind ("synth_aggregate", Aggr_Type);
end case;
@@ -2178,6 +2244,22 @@ package body Synth.Expr is
return Synth_Indexed_Name (Syn_Inst, Expr);
when Iir_Kind_Slice_Name =>
return Synth_Slice_Name (Syn_Inst, Expr);
+ when Iir_Kind_Selected_Element =>
+ declare
+ Idx : constant Iir_Index32 :=
+ Get_Element_Position (Get_Named_Entity (Expr));
+ Pfx : constant Node := Get_Prefix (Expr);
+ Res_Typ : Type_Acc;
+ N : Net;
+ begin
+ Res := Synth_Expression (Syn_Inst, Pfx);
+ Res_Typ := Res.Typ.Rec.E (Idx + 1).Typ;
+ -- FIXME: handle const.
+ N := Build_Extract
+ (Build_Context, Get_Net (Res),
+ Res.Typ.Rec.E (Idx + 1).Off, Get_Type_Width (Res_Typ));
+ return Create_Value_Net (N, Res_Typ);
+ end;
when Iir_Kind_Character_Literal =>
return Synth_Expression_With_Type
(Syn_Inst, Get_Named_Entity (Expr), Expr_Type);