aboutsummaryrefslogtreecommitdiffstats
path: root/src/vhdl
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-07-27 18:47:33 +0200
committerTristan Gingold <tgingold@free.fr>2020-07-27 18:47:33 +0200
commit9579af7882b3862e426b2f129d86c74943d0e5f9 (patch)
tree58b90779810505f82d25774d772d27a067a1c492 /src/vhdl
parentc16acb52daa0037bcf52af9413b99ef69d5c0257 (diff)
downloadghdl-9579af7882b3862e426b2f129d86c74943d0e5f9.tar.gz
ghdl-9579af7882b3862e426b2f129d86c74943d0e5f9.tar.bz2
ghdl-9579af7882b3862e426b2f129d86c74943d0e5f9.zip
translate: handle slice of arrays with unbounded elements.
Diffstat (limited to 'src/vhdl')
-rw-r--r--src/vhdl/translate/trans-chap3.adb26
-rw-r--r--src/vhdl/translate/trans-chap3.ads14
-rw-r--r--src/vhdl/translate/trans-chap6.adb55
-rw-r--r--src/vhdl/translate/trans-chap7.adb6
-rw-r--r--src/vhdl/translate/trans-chap8.adb5
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);