diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-07-27 18:47:33 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-07-27 18:47:33 +0200 |
commit | 9579af7882b3862e426b2f129d86c74943d0e5f9 (patch) | |
tree | 58b90779810505f82d25774d772d27a067a1c492 /src | |
parent | c16acb52daa0037bcf52af9413b99ef69d5c0257 (diff) | |
download | ghdl-9579af7882b3862e426b2f129d86c74943d0e5f9.tar.gz ghdl-9579af7882b3862e426b2f129d86c74943d0e5f9.tar.bz2 ghdl-9579af7882b3862e426b2f129d86c74943d0e5f9.zip |
translate: handle slice of arrays with unbounded elements.
Diffstat (limited to 'src')
-rw-r--r-- | src/vhdl/translate/trans-chap3.adb | 26 | ||||
-rw-r--r-- | src/vhdl/translate/trans-chap3.ads | 14 | ||||
-rw-r--r-- | src/vhdl/translate/trans-chap6.adb | 55 | ||||
-rw-r--r-- | src/vhdl/translate/trans-chap7.adb | 6 | ||||
-rw-r--r-- | src/vhdl/translate/trans-chap8.adb | 5 |
5 files changed, 83 insertions, 23 deletions
diff --git a/src/vhdl/translate/trans-chap3.adb b/src/vhdl/translate/trans-chap3.adb index 17cc5ef4c..b88881ed3 100644 --- a/src/vhdl/translate/trans-chap3.adb +++ b/src/vhdl/translate/trans-chap3.adb @@ -3049,17 +3049,29 @@ package body Trans.Chap3 is end if; end Index_Array; - function Slice_Base (Base : Mnode; Atype : Iir; Index : O_Enode) - return Mnode + function Slice_Base + (Base : Mnode; Atype : Iir; Index : O_Enode; Stride : O_Enode) + return Mnode is T_Info : constant Type_Info_Acc := Get_Info (Atype); El_Type : constant Iir := Get_Element_Subtype (Atype); El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type); Kind : constant Object_Kind_Type := Get_Object_Kind (Base); begin - if Is_Complex_Type (El_Tinfo) then - return Reindex_Complex_Array (Base, Atype, Index, T_Info); - elsif T_Info.Type_Mode = Type_Mode_Static_Array then + if not Is_Static_Type (El_Tinfo) then + pragma Assert (T_Info.Type_Mode /= Type_Mode_Static_Array); + if Stride /= O_Enode_Null then + return E2M + (Add_Pointer (M2E (Base), + New_Dyadic_Op (ON_Mul_Ov, Stride, Index), + T_Info.Ortho_Ptr_Type (Kind)), + T_Info, Kind); + else + return Reindex_Complex_Array (Base, Atype, Index, T_Info); + end if; + end if; + + if T_Info.Type_Mode = Type_Mode_Static_Array then -- Static array. Use the type of the array. return Lv2M (New_Slice (M2Lv (Base), T_Info.Ortho_Type (Kind), @@ -3124,7 +3136,7 @@ package body Trans.Chap3 is Chap3.Elab_Composite_Subtype_Layout (Arr_Type); end Elab_Array_Subtype; - procedure Create_Composite_Subtype (Sub_Type : Iir) + procedure Create_Composite_Subtype (Sub_Type : Iir; Elab : Boolean := True) is Mark : Id_Mark_Type; begin @@ -3134,7 +3146,7 @@ package body Trans.Chap3 is Translate_Subtype_Definition (Sub_Type, False); end if; -- Force creation of variables. - Chap3.Create_Composite_Subtype_Layout_Var (Sub_Type, True); + Chap3.Create_Composite_Subtype_Layout_Var (Sub_Type, Elab); Pop_Identifier_Prefix (Mark); end Create_Composite_Subtype; diff --git a/src/vhdl/translate/trans-chap3.ads b/src/vhdl/translate/trans-chap3.ads index 88730ee84..bf524d43c 100644 --- a/src/vhdl/translate/trans-chap3.ads +++ b/src/vhdl/translate/trans-chap3.ads @@ -152,8 +152,9 @@ package Trans.Chap3 is return Mnode; -- Same for for slicing. - function Slice_Base (Base : Mnode; Atype : Iir; Index : O_Enode) - return Mnode; + function Slice_Base + (Base : Mnode; Atype : Iir; Index : O_Enode; Stride : O_Enode) + return Mnode; -- Get the length of the array (the number of elements). function Get_Array_Length (Arr : Mnode; Atype : Iir) return O_Enode; @@ -217,6 +218,9 @@ package Trans.Chap3 is -- Return bounds from layout B. function Layout_To_Bounds (B : Mnode) return Mnode; + function Layout_To_Size (Layout : Mnode; Kind : Object_Kind_Type) + return O_Lnode; + -- From a record layout B, return the layout of element EL. EL must be -- an unbounded element. function Record_Layout_To_Element_Layout (B : Mnode; El : Iir) return Mnode; @@ -292,13 +296,17 @@ package Trans.Chap3 is -- Used for alias: create the vars for the subtype of the name (when the -- name is a slice). The identifier prefix must have been set. + -- + -- Slices are special because they create new bounds variables. These + -- variables are expected to be transcient. But in some cases (like + -- aliases), they have a longer life. procedure Translate_Array_Subtype (Arr_Type : Iir); procedure Elab_Array_Subtype (Arr_Type : Iir); -- Create the bounds for SUB_TYPE. -- SUB_TYPE is expected to be a non-static, anonymous array or record -- subtype. - procedure Create_Composite_Subtype (Sub_Type : Iir); + procedure Create_Composite_Subtype (Sub_Type : Iir; Elab : Boolean := True); -- Return TRUE if VALUE is not is the range specified by ATYPE. -- VALUE must be stable. diff --git a/src/vhdl/translate/trans-chap6.adb b/src/vhdl/translate/trans-chap6.adb index 00da53235..b4f8008c6 100644 --- a/src/vhdl/translate/trans-chap6.adb +++ b/src/vhdl/translate/trans-chap6.adb @@ -559,16 +559,20 @@ package body Trans.Chap6 is -- Type of the first (and only) index of the prefix array type. Index_Type : constant Iir := Get_Index_Type (Prefix_Type, 0); + -- Element type. + El_Type : constant Iir := Get_Element_Subtype (Prefix_Type); + El_Tinfo : constant Type_Info_Acc := Get_Info (El_Type); + -- Type of the slice. Slice_Type : constant Iir := Get_Type (Expr); Slice_Info : Type_Info_Acc; - -- True iff the direction of the slice is known at compile time. - Static_Range : Boolean; - -- Suffix of the slice (discrete range). Expr_Range : constant Iir := Get_Suffix (Expr); + -- True iff the direction of the slice is known at compile time. + Static_Range : Boolean; + -- Variable pointing to the prefix. Prefix_Var : Mnode; @@ -584,11 +588,32 @@ package body Trans.Chap6 is Unsigned_Diff : O_Dnode; If_Blk, If_Blk1 : O_If_Block; begin - -- Evaluate slice bounds. - Chap3.Create_Composite_Subtype (Slice_Type); + pragma Assert (Get_Info (Prefix_Type) /= null); + -- Evaluate slice bounds. + Chap3.Create_Composite_Subtype (Slice_Type, False); -- The info may have just been created. Prefix_Info := Get_Info (Prefix_Type); + + Prefix_Var := Prefix; + + if Is_Unbounded_Type (El_Tinfo) then + -- Copy layout of element before building the bounds + pragma Assert (Is_Unbounded_Type (Prefix_Info)); + Stabilize (Prefix_Var); + Gen_Memcpy + (M2Addr (Chap3.Array_Bounds_To_Element_Layout + (Chap3.Get_Composite_Type_Bounds (Slice_Type), + Slice_Type)), + M2Addr (Chap3.Array_Bounds_To_Element_Layout + (Chap3.Get_Composite_Bounds (Prefix_Var), + Prefix_Type)), + New_Lit (New_Sizeof (El_Tinfo.B.Layout_Type, + Ghdl_Index_Type))); + end if; + Chap3.Elab_Array_Subtype (Slice_Type); + + -- The info may have just been created. Slice_Info := Get_Info (Slice_Type); if Slice_Info.Type_Mode = Type_Mode_Static_Array @@ -652,7 +677,7 @@ package body Trans.Chap6 is Data.Is_Off := False; -- Save prefix. - Prefix_Var := Stabilize (Prefix); + Stabilize (Prefix_Var); Index_Info := Get_Info (Get_Base_Type (Index_Type)); @@ -797,12 +822,23 @@ package body Trans.Chap6 is Kind : constant Object_Kind_Type := Get_Object_Kind (Prefix); Off : O_Enode; + El_Size : O_Enode; Res_Base : Mnode; Res_D : O_Dnode; begin if Is_Unbounded_Type (El_Tinfo) then - raise Internal_Error; + -- pragma Assert (Is_Unbounded_Type (Slice_Tinfo)); + El_Size := New_Value + (Chap3.Layout_To_Size + (Chap3.Array_Bounds_To_Element_Layout + (Chap3.Get_Composite_Bounds (Data.Prefix_Var), Slice_Type), + Kind)); + elsif Is_Complex_Type (El_Tinfo) then + El_Size := Chap3.Get_Subtype_Size (El_Type, Mnode_Null, Kind); + else + pragma Assert (Is_Static_Type (El_Tinfo)); + El_Size := O_Enode_Null; end if; if Data.Is_Off then @@ -812,7 +848,7 @@ package body Trans.Chap6 is end if; Res_Base := Chap3.Slice_Base - (Chap3.Get_Composite_Base (Prefix), Slice_Type, Off); + (Chap3.Get_Composite_Base (Prefix), Slice_Type, Off, El_Size); case Type_Mode_Arrays (Slice_Tinfo.Type_Mode) is when Type_Mode_Unbounded_Array => @@ -826,7 +862,8 @@ package body Trans.Chap6 is (New_Selected_Element (New_Obj (Res_D), Slice_Tinfo.B.Bounds_Field (Kind)), New_Value (M2Lp (Data.Slice_Range))); - return Dv2M (Res_D, Slice_Tinfo, Kind); + raise Internal_Error; + --return Dv2M (Res_D, Slice_Tinfo, Kind); when Type_Mode_Bounded_Arrays => return Res_Base; end case; diff --git a/src/vhdl/translate/trans-chap7.adb b/src/vhdl/translate/trans-chap7.adb index add6deaf8..63640a03d 100644 --- a/src/vhdl/translate/trans-chap7.adb +++ b/src/vhdl/translate/trans-chap7.adb @@ -1474,7 +1474,8 @@ package body Trans.Chap7 is New_Convert_Ov (M2Addr (Chap3.Slice_Base (Var_Arr, Expr_Type, - New_Obj_Value (Var_Off))), + New_Obj_Value (Var_Off), + O_Enode_Null)), Info.B.Base_Ptr_Type (Mode_Value))); -- Copy @@ -2989,7 +2990,8 @@ package body Trans.Chap7 is Inc_Var (Var_Index); else Dest := Chap3.Slice_Base (Base_Ptr, Aggr_Type, - New_Obj_Value (Var_Index)); + New_Obj_Value (Var_Index), + O_Enode_Null); Translate_Assign (Dest, Expr, Get_Type (Expr)); -- FIXME: handle non-static expression type (at least for -- choice by range). diff --git a/src/vhdl/translate/trans-chap8.adb b/src/vhdl/translate/trans-chap8.adb index 9028c16e7..5d662f410 100644 --- a/src/vhdl/translate/trans-chap8.adb +++ b/src/vhdl/translate/trans-chap8.adb @@ -962,7 +962,8 @@ package body Trans.Chap8 is else Sub_Type := Get_Type (Targ); Sub_Aggr := Chap3.Slice_Base (Chap3.Get_Composite_Base (Val), - Sub_Type, New_Obj_Value (Index)); + Sub_Type, New_Obj_Value (Index), + O_Enode_Null); Stabilize (Sub_Aggr); Dest := Chap6.Translate_Name (Targ, Mode_Value); Stabilize (Dest); @@ -4231,7 +4232,7 @@ package body Trans.Chap8 is else Sub_Type := Get_Type (Expr); Sub_Aggr := Chap3.Slice_Base - (Aggr, Sub_Type, New_Obj_Value (Idx)); + (Aggr, Sub_Type, New_Obj_Value (Idx), O_Enode_Null); end if; when others => Error_Kind ("translate_signal_target_array_aggr", El); |