From b043fa31841362c17b2bb937d35a55c544a0a029 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Fri, 9 Nov 2018 03:05:12 +0100 Subject: vhdl/translate: improve support of unbounded arrays. --- src/vhdl/translate/trans-chap3.adb | 76 +++++++++++++++++++++++--------------- src/vhdl/translate/trans-chap4.adb | 11 +++--- src/vhdl/translate/trans-chap6.adb | 52 +++++++++++++++++++------- src/vhdl/translate/trans-chap6.ads | 7 ++++ src/vhdl/translate/trans-chap8.adb | 8 ++-- src/vhdl/translate/trans-chap9.adb | 4 +- 6 files changed, 102 insertions(+), 56 deletions(-) diff --git a/src/vhdl/translate/trans-chap3.adb b/src/vhdl/translate/trans-chap3.adb index 9ebd6f656..2d6b2d038 100644 --- a/src/vhdl/translate/trans-chap3.adb +++ b/src/vhdl/translate/trans-chap3.adb @@ -2969,7 +2969,8 @@ package body Trans.Chap3 is Kind : constant Object_Kind_Type := Get_Object_Kind (Base); begin if Is_Unbounded_Type (El_Tinfo) then - -- It's not possible to index an unbounded array with only the base. + -- It's not possible to index an unbounded array with only the base, + -- as the size of an element is not known. -- Index_Array must be used instead. raise Internal_Error; elsif Is_Complex_Type (El_Tinfo) then @@ -2987,27 +2988,35 @@ package body Trans.Chap3 is El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type); Kind : constant Object_Kind_Type := Get_Object_Kind (Arr); begin - if Is_Unbounded_Type (El_Tinfo) then - return E2M - (Add_Pointer - (M2E (Get_Composite_Base (Arr)), - New_Dyadic_Op - (ON_Mul_Ov, - Index, - New_Value (Array_Bounds_To_Element_Size - (Get_Composite_Bounds (Arr), Atype))), - El_Tinfo.B.Base_Ptr_Type (Kind)), - El_Tinfo, Kind, - El_Tinfo.B.Base_Type (Kind), - El_Tinfo.B.Base_Ptr_Type (Kind)); - elsif Is_Complex_Type (El_Tinfo) then - return Reindex_Complex_Array - (Get_Composite_Base (Arr), Atype, Index, El_Tinfo); - else - return Lv2M - (New_Indexed_Element (M2Lv (Get_Composite_Base (Arr)), Index), - El_Tinfo, Kind); - end if; + -- For indexing, we need to consider the size of elements. + case Type_Mode_Valid (El_Tinfo.Type_Mode) is + when Type_Mode_Unbounded_Array + | Type_Mode_Unbounded_Record => + return E2M + (Add_Pointer + (M2E (Get_Composite_Base (Arr)), + New_Dyadic_Op + (ON_Mul_Ov, + Index, + New_Value (Array_Bounds_To_Element_Size + (Get_Composite_Bounds (Arr), Atype))), + El_Tinfo.B.Base_Ptr_Type (Kind)), + El_Tinfo, Kind, + El_Tinfo.B.Base_Type (Kind), + El_Tinfo.B.Base_Ptr_Type (Kind)); + when Type_Mode_Complex_Array + | Type_Mode_Complex_Record => + return Reindex_Complex_Array + (Get_Composite_Base (Arr), Atype, Index, El_Tinfo); + when Type_Mode_Thin + | Type_Mode_Static_Array + | Type_Mode_Static_Record => + return Lv2M + (New_Indexed_Element (M2Lv (Get_Composite_Base (Arr)), Index), + El_Tinfo, Kind); + when Type_Mode_Protected => + raise Internal_Error; + end case; end Index_Array; function Slice_Base (Base : Mnode; Atype : Iir; Index : O_Enode) @@ -3140,18 +3149,26 @@ package body Trans.Chap3 is | Type_Mode_Complex_Record => -- The length is pre-computed for a complex bounded type. return New_Value - (Sizes_To_Size - (Layout_To_Sizes - (Get_Composite_Type_Layout (Type_Info)), Kind)); + (Layout_To_Size (Get_Composite_Type_Layout (Type_Info), Kind)); when Type_Mode_Unbounded_Array => declare El_Type : constant Iir := Get_Element_Subtype (Atype); + El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type); El_Sz : O_Enode; + Bounds1 : Mnode; begin - -- FIXME: unbounded elements ? - El_Sz := Get_Subtype_Size (El_Type, Mnode_Null, Kind); + if El_Tinfo.Type_Mode in Type_Mode_Unbounded then + Bounds1 := Stabilize (Bounds); + El_Sz := New_Value + (Layout_To_Size + (Array_Bounds_To_Element_Layout (Bounds1, Atype), + Kind)); + else + Bounds1 := Bounds; + El_Sz := Get_Subtype_Size (El_Type, Mnode_Null, Kind); + end if; return New_Dyadic_Op - (ON_Mul_Ov, Chap3.Get_Bounds_Length (Bounds, Atype), El_Sz); + (ON_Mul_Ov, Chap3.Get_Bounds_Length (Bounds1, Atype), El_Sz); end; when Type_Mode_Unbounded_Record => return New_Value (Sizes_To_Size (Layout_To_Sizes (Bounds), Kind)); @@ -3160,8 +3177,7 @@ package body Trans.Chap3 is end case; end Get_Subtype_Size; - function Get_Object_Size (Obj : Mnode; Obj_Type : Iir) - return O_Enode + function Get_Object_Size (Obj : Mnode; Obj_Type : Iir) return O_Enode is Type_Info : constant Type_Info_Acc := Get_Type_Info (Obj); Kind : constant Object_Kind_Type := Get_Object_Kind (Obj); diff --git a/src/vhdl/translate/trans-chap4.adb b/src/vhdl/translate/trans-chap4.adb index 69577161e..0814f4974 100644 --- a/src/vhdl/translate/trans-chap4.adb +++ b/src/vhdl/translate/trans-chap4.adb @@ -360,12 +360,11 @@ package body Trans.Chap4 is end if; Gen_Exit_When (Label, New_Compare_Op (ON_Eq, - New_Obj_Value (Index), Upper_Limit, - Ghdl_Bool_Type)); - Init_Object (Chap3.Index_Base (Chap3.Get_Composite_Base (Sobj), - Obj_Type, - New_Obj_Value (Index)), - Get_Element_Subtype (Obj_Type)); + New_Obj_Value (Index), Upper_Limit, + Ghdl_Bool_Type)); + Init_Object + (Chap6.Translate_Indexed_Name_By_Offset (Sobj, Obj_Type, Index), + Get_Element_Subtype (Obj_Type)); Inc_Var (Index); Finish_Loop_Stmt (Label); diff --git a/src/vhdl/translate/trans-chap6.adb b/src/vhdl/translate/trans-chap6.adb index 24ba5ea96..a812f3331 100644 --- a/src/vhdl/translate/trans-chap6.adb +++ b/src/vhdl/translate/trans-chap6.adb @@ -448,13 +448,33 @@ package body Trans.Chap6 is return Offset; end Translate_Indexed_Name_Offset; - function Translate_Indexed_Name_Finish - (Prefix : Mnode; Expr : Iir; Offset : O_Dnode) return Mnode is + function Translate_Indexed_Name_By_Offset + (Prefix : Mnode; Prefix_Type : Iir; Offset : O_Dnode) return Mnode + is + El_Type : constant Iir := Get_Element_Subtype (Prefix_Type); + El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type); + Kind : constant Object_Kind_Type := Get_Object_Kind (Prefix); + Fat_Res : Mnode; + Base : Mnode; + Bounds : Mnode; begin - return Chap3.Index_Base (Chap3.Get_Composite_Base (Prefix), - Get_Type (Get_Prefix (Expr)), - New_Obj_Value (Offset)); - end Translate_Indexed_Name_Finish; + Base := Chap3.Index_Array (Prefix, Prefix_Type, New_Obj_Value (Offset)); + + if Is_Unbounded_Type (El_Tinfo) then + Fat_Res := Create_Temp (El_Tinfo, Kind); + Bounds := Chap3.Get_Composite_Bounds (Prefix); + Bounds := Chap3.Array_Bounds_To_Element_Bounds (Bounds, Prefix_Type); + + -- Assignment to M2Lp works as this is not a copy. + New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Bounds (Fat_Res)), + M2Addr (Bounds)); + New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Base (Fat_Res)), + M2Addr (Base)); + return Fat_Res; + else + return Base; + end if; + end Translate_Indexed_Name_By_Offset; function Translate_Indexed_Name (Prefix : Mnode; Expr : Iir) return Mnode is @@ -463,7 +483,8 @@ package body Trans.Chap6 is begin Stable_Prefix := Stabilize_If_Unbounded (Prefix); Offset := Translate_Indexed_Name_Offset (Stable_Prefix, Expr); - return Translate_Indexed_Name_Finish (Stable_Prefix, Expr, Offset); + return Translate_Indexed_Name_By_Offset + (Stable_Prefix, Get_Type (Get_Prefix (Expr)), Offset); end Translate_Indexed_Name; type Slice_Name_Data is record @@ -923,10 +944,9 @@ package body Trans.Chap6 is end if; if Is_Unbounded_Type (El_Tinfo) then - New_Assign_Stmt - (New_Selected_Element (M2Lv (Fat_Res), - El_Tinfo.B.Base_Field (Kind)), - M2Addr (Res)); + -- Ok, we know that Get_Composite_Base doesn't return a copy. + New_Assign_Stmt (M2Lp (Chap3.Get_Composite_Base (Fat_Res)), + M2Addr (Res)); return Fat_Res; else return Res; @@ -1219,15 +1239,19 @@ package body Trans.Chap6 is end; when Iir_Kind_Indexed_Name => declare + Prefix : constant Iir := Get_Prefix (Name); + Prefix_Type : constant Iir := Get_Type (Prefix); Offset : O_Dnode; Pfx_Sig : Mnode; Pfx_Drv : Mnode; begin - Translate_Signal (Get_Prefix (Name), Pfx_Sig, Pfx_Drv); + Translate_Signal (Prefix, Pfx_Sig, Pfx_Drv); Pfx_Sig := Stabilize_If_Unbounded (Pfx_Sig); Offset := Translate_Indexed_Name_Offset (Pfx_Sig, Name); - Sig := Translate_Indexed_Name_Finish (Pfx_Sig, Name, Offset); - Drv := Translate_Indexed_Name_Finish (Pfx_Drv, Name, Offset); + Sig := Translate_Indexed_Name_By_Offset + (Pfx_Sig, Prefix_Type, Offset); + Drv := Translate_Indexed_Name_By_Offset + (Pfx_Drv, Prefix_Type, Offset); end; when Iir_Kind_Selected_Element => declare diff --git a/src/vhdl/translate/trans-chap6.ads b/src/vhdl/translate/trans-chap6.ads index d5822c4e0..09538c569 100644 --- a/src/vhdl/translate/trans-chap6.ads +++ b/src/vhdl/translate/trans-chap6.ads @@ -44,6 +44,13 @@ package Trans.Chap6 is function Translate_Selected_Element (Prefix : Mnode; El : Iir_Element_Declaration) return Mnode; + -- Get array element at OFFSET of PREFIX. If unbounded, PREFIX must be + -- stabilized. + function Translate_Indexed_Name_By_Offset + (Prefix : Mnode; Prefix_Type : Iir; Offset : O_Dnode) return Mnode; + + function Stabilize_If_Unbounded (Val : Mnode) return Mnode; + function Get_Array_Bound_Length (Arr : Mnode; Arr_Type : Iir; Dim : Natural) return O_Enode; diff --git a/src/vhdl/translate/trans-chap8.adb b/src/vhdl/translate/trans-chap8.adb index 5709fb1c0..4ae0742d6 100644 --- a/src/vhdl/translate/trans-chap8.adb +++ b/src/vhdl/translate/trans-chap8.adb @@ -4123,10 +4123,10 @@ package body Trans.Chap8 is return Signal_Direct_Assign_Data is begin return Signal_Direct_Assign_Data' - (Drv => Chap3.Index_Array (Val.Drv, Targ_Type, - New_Obj_Value (Index)), - Expr => Chap3.Index_Array (Val.Expr, Targ_Type, - New_Obj_Value (Index)), + (Drv => Chap6.Translate_Indexed_Name_By_Offset + (Val.Drv, Targ_Type, Index), + Expr => Chap6.Translate_Indexed_Name_By_Offset + (Val.Expr, Targ_Type, Index), Expr_Node => Val.Expr_Node); end Gen_Signal_Direct_Update_Data_Array; diff --git a/src/vhdl/translate/trans-chap9.adb b/src/vhdl/translate/trans-chap9.adb index 3213e50a0..1fbd4e8e6 100644 --- a/src/vhdl/translate/trans-chap9.adb +++ b/src/vhdl/translate/trans-chap9.adb @@ -1400,8 +1400,8 @@ package body Trans.Chap9 is if Val = Mnode_Null then return Mnode_Null; else - return Chap3.Index_Base (Chap3.Get_Composite_Base (Val), - Targ_Type, New_Obj_Value (Index)); + return Chap6.Translate_Indexed_Name_By_Offset + (Chap6.Stabilize_If_Unbounded (Val), Targ_Type, Index); end if; end Foreach_Non_Composite_Update_Data_Array_Mnode; -- cgit v1.2.3