aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2023-02-05 10:40:08 +0100
committerTristan Gingold <tgingold@free.fr>2023-02-05 10:40:08 +0100
commitd78acf8f24949f608fa0dd20719ea67ba5621a5c (patch)
tree46fb85bd36986a5aa2bae98fcc33c7ddbf600dfd
parent71143862c7194c7ddddd76201cccadedb3471553 (diff)
downloadghdl-d78acf8f24949f608fa0dd20719ea67ba5621a5c.tar.gz
ghdl-d78acf8f24949f608fa0dd20719ea67ba5621a5c.tar.bz2
ghdl-d78acf8f24949f608fa0dd20719ea67ba5621a5c.zip
synth: preliminary work to compute access bounds size
-rw-r--r--src/synth/elab-vhdl_objtypes.adb122
-rw-r--r--src/synth/elab-vhdl_objtypes.ads7
-rw-r--r--src/synth/elab-vhdl_types.adb1
3 files changed, 128 insertions, 2 deletions
diff --git a/src/synth/elab-vhdl_objtypes.adb b/src/synth/elab-vhdl_objtypes.adb
index 6f3c88675..9c20cc377 100644
--- a/src/synth/elab-vhdl_objtypes.adb
+++ b/src/synth/elab-vhdl_objtypes.adb
@@ -675,17 +675,135 @@ package body Elab.Vhdl_Objtypes is
Rec => Els)));
end Create_Unbounded_Record;
+ -- Compute size and alignment for bounds of TYP.
+ procedure Update_Bounds_Size (Typ : Type_Acc;
+ Sz : in out Size_Type;
+ Al : in out Palign_Type);
+
+ procedure Update_Layout_Size (Typ : Type_Acc;
+ Sz : in out Size_Type;
+ Al : in out Palign_Type) is
+ begin
+ case Typ.Kind is
+ when Type_Scalars
+ | Type_Array
+ | Type_Vector
+ | Type_Record
+ | Type_Access =>
+ null;
+ when Type_Unbounded_Vector
+ | Type_Unbounded_Array =>
+ declare
+ B_Sz : Size_Type;
+ B_Al : Palign_Type;
+ begin
+ -- Layout of an array is sizes + bounds.
+ B_Sz := 2 * Ghdl_Index_Sz;
+ B_Al := Ghdl_Index_Al;
+ Update_Bounds_Size (Typ, B_Sz, B_Al);
+ Sz := Align (Sz, B_Al);
+ Sz := Sz + B_Sz;
+ Al := Palign_Type'Max (Al, B_Al);
+ end;
+ when Type_Unbounded_Record
+ | Type_Array_Unbounded =>
+ -- TODO
+ raise Internal_Error;
+ when Type_Slice
+ | Type_File
+ | Type_Protected =>
+ raise Internal_Error;
+ end case;
+ end Update_Layout_Size;
+
+ procedure Update_Bounds_Size (Typ : Type_Acc;
+ Sz : in out Size_Type;
+ Al : in out Palign_Type) is
+ begin
+ case Typ.Kind is
+ when Type_Scalars
+ | Type_Array
+ | Type_Vector
+ | Type_Record
+ | Type_Access =>
+ null;
+ when Type_Array_Unbounded =>
+ Update_Bounds_Size (Typ.Arr_El, Sz, Al);
+ when Type_Unbounded_Array
+ | Type_Unbounded_Vector =>
+ declare
+ Idx : constant Type_Acc := Typ.Uarr_Idx;
+ B_Sz : Size_Type;
+ B_Al : Palign_Type;
+ begin
+ -- Compute size of left, right and dir fields.
+ case Idx.Sz is
+ when 1 =>
+ B_Sz := 3;
+ B_Al := 0;
+ when 4 =>
+ B_Sz := 9;
+ B_Al := 2;
+ when 8 =>
+ B_Sz := 17;
+ B_Al := 2;
+ when others =>
+ raise Internal_Error;
+ end case;
+ -- Add length field.
+ Sz := Align (Sz, Ghdl_Index_Al);
+ B_Sz := B_Sz + Ghdl_Index_Sz;
+ -- Compute whole alignment.
+ B_Al := Palign_Type'Max (3, Ghdl_Index_Al);
+ B_Sz := Align (B_Sz, B_Al);
+ -- Add to the result.
+ Sz := Align (Sz, B_Al);
+ Sz := Sz + B_Sz;
+
+ if not Typ.Ulast then
+ -- Continue with next index.
+ Update_Bounds_Size (Typ.Uarr_El, Sz, Al);
+ else
+ -- Continue with the element.
+ Update_Layout_Size (Typ.Uarr_El, Sz, Al);
+ end if;
+
+ end;
+ when Type_Unbounded_Record =>
+ -- TODO
+ raise Internal_Error;
+ when Type_Slice
+ | Type_File
+ | Type_Protected =>
+ raise Internal_Error;
+ end case;
+ end Update_Bounds_Size;
+
+ function Compute_Bounds_Size (Typ : Type_Acc) return Size_Type
+ is
+ Res : Size_Type;
+ Al : Palign_Type;
+ begin
+ Res := 0;
+ Al := 0;
+ Update_Bounds_Size (Typ, Res, Al);
+ return Res;
+ end Compute_Bounds_Size;
+
function Create_Access_Type (Acc_Type : Type_Acc) return Type_Acc
is
subtype Access_Type_Type is Type_Type (Type_Access);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Access_Type_Type);
Type_Sz : Size_Type;
+ Bnd_Sz : Size_Type;
begin
if Acc_Type = null then
-- For incomplete type.
Type_Sz := 0;
+ Bnd_Sz := 0;
else
Type_Sz := Compute_Size_Type (Acc_Type);
+ Bnd_Sz := Compute_Bounds_Size (Acc_Type);
end if;
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Access,
Wkind => Wkind_Sim,
@@ -694,13 +812,15 @@ package body Elab.Vhdl_Objtypes is
Sz => Heap_Ptr_Sz,
W => 1,
Acc_Acc => Acc_Type,
- Acc_Type_Sz => Type_Sz)));
+ Acc_Type_Sz => Type_Sz,
+ Acc_Bnd_Sz => Bnd_Sz)));
end Create_Access_Type;
procedure Complete_Access_Type (Acc_Type : Type_Acc; Des_Typ : Type_Acc) is
begin
Acc_Type.Acc_Acc := Des_Typ;
Acc_Type.Acc_Type_Sz := Compute_Size_Type (Des_Typ);
+ Acc_Type.Acc_Bnd_Sz := Compute_Bounds_Size (Des_Typ);
end Complete_Access_Type;
function Create_File_Type (File_Type : Type_Acc) return Type_Acc
diff --git a/src/synth/elab-vhdl_objtypes.ads b/src/synth/elab-vhdl_objtypes.ads
index a310cce27..8862f44c7 100644
--- a/src/synth/elab-vhdl_objtypes.ads
+++ b/src/synth/elab-vhdl_objtypes.ads
@@ -200,8 +200,9 @@ package Elab.Vhdl_Objtypes is
Rec : Rec_El_Array_Acc;
when Type_Access =>
Acc_Acc : Type_Acc;
- -- Memory size to store the type.
+ -- Memory size to store the type and its bounds.
Acc_Type_Sz : Size_Type;
+ Acc_Bnd_Sz : Size_Type;
when Type_File =>
File_Typ : Type_Acc;
File_Signature : String_Acc;
@@ -227,6 +228,10 @@ package Elab.Vhdl_Objtypes is
2 * Boolean'Pos (Heap_Ptr_Sz = 4)
+ 3 * Boolean'Pos (Heap_Ptr_Sz = 8);
+ -- Ghdl_Index_Type is a 32b unsigned type.
+ Ghdl_Index_Sz : constant Size_Type := 4;
+ Ghdl_Index_Al : constant Palign_Type := 2;
+
-- Memory pools, which defines where the memory is allocated for data,
-- types, values...
diff --git a/src/synth/elab-vhdl_types.adb b/src/synth/elab-vhdl_types.adb
index e4963a11e..75f27a888 100644
--- a/src/synth/elab-vhdl_types.adb
+++ b/src/synth/elab-vhdl_types.adb
@@ -325,6 +325,7 @@ package body Elab.Vhdl_Types is
Des_Typ : Type_Acc;
Typ : Type_Acc;
begin
+ -- Need to handle incomplete access type.
if Get_Kind (Des_Ind) in Iir_Kinds_Denoting_Name then
T := Get_Named_Entity (Des_Ind);
if Get_Kind (T) = Iir_Kind_Type_Declaration