aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vhdl/translate/trans-chap3.adb76
-rw-r--r--src/vhdl/translate/trans-chap4.adb11
-rw-r--r--src/vhdl/translate/trans-chap6.adb52
-rw-r--r--src/vhdl/translate/trans-chap6.ads7
-rw-r--r--src/vhdl/translate/trans-chap8.adb8
-rw-r--r--src/vhdl/translate/trans-chap9.adb4
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;