aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2023-04-07 21:04:43 +0200
committerTristan Gingold <tgingold@free.fr>2023-04-07 21:04:43 +0200
commitbdc1c9cf6db576e585d60e531da14a4c8d72333d (patch)
tree80453d6eb8e9a505b3f99fa34db41e246e1e864c /src
parent43b8fb03d707c908a94519b8217b83d37736a633 (diff)
downloadghdl-bdc1c9cf6db576e585d60e531da14a4c8d72333d.tar.gz
ghdl-bdc1c9cf6db576e585d60e531da14a4c8d72333d.tar.bz2
ghdl-bdc1c9cf6db576e585d60e531da14a4c8d72333d.zip
translation: improve type conversion (recurse)
Diffstat (limited to 'src')
-rw-r--r--src/vhdl/translate/trans-chap5.adb2
-rw-r--r--src/vhdl/translate/trans-chap7.adb198
-rw-r--r--src/vhdl/translate/trans-chap7.ads2
3 files changed, 120 insertions, 82 deletions
diff --git a/src/vhdl/translate/trans-chap5.adb b/src/vhdl/translate/trans-chap5.adb
index 2c91f36f2..59cdc41c3 100644
--- a/src/vhdl/translate/trans-chap5.adb
+++ b/src/vhdl/translate/trans-chap5.adb
@@ -649,7 +649,7 @@ package body Trans.Chap5 is
Res_Type := Get_Type (Get_Association_Interface (Assoc, Inter));
Bounds := Get_Actual_Bounds (False);
Res := Alloc_Bounds (Res_Type, Alloc_System);
- Chap7.Translate_Type_Conversion_Bounds
+ Chap7.Translate_Type_Conversion_Array_Bounds
(Res, Bounds, Res_Type, Actual_Type, Assoc);
return Res;
end Get_Unconstrained_Port_Bounds;
diff --git a/src/vhdl/translate/trans-chap7.adb b/src/vhdl/translate/trans-chap7.adb
index 237643133..3192fe305 100644
--- a/src/vhdl/translate/trans-chap7.adb
+++ b/src/vhdl/translate/trans-chap7.adb
@@ -4519,74 +4519,8 @@ package body Trans.Chap7 is
end case;
end Translate_Allocator_By_Subtype;
- function Translate_Fat_Array_Type_Conversion
- (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir)
- return O_Enode;
-
- function Translate_Array_Subtype_Conversion
- (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir)
- return O_Enode
- is
- Res_Info : constant Type_Info_Acc := Get_Info (Res_Type);
- Expr_Info : constant Type_Info_Acc := Get_Info (Expr_Type);
- E : Mnode;
- begin
- E := Stabilize (E2M (Expr, Expr_Info, Mode_Value));
- case Res_Info.Type_Mode is
- when Type_Mode_Bounded_Arrays =>
- Chap3.Check_Composite_Match
- (Res_Type, T2M (Res_Type, Mode_Value),
- Expr_Type, E,
- Loc);
- return New_Convert_Ov
- (M2Addr (Chap3.Get_Composite_Base (E)),
- Res_Info.Ortho_Ptr_Type (Mode_Value));
- when Type_Mode_Unbounded_Array =>
- declare
- Res : Mnode;
- begin
- Res := Create_Temp (Res_Info);
- Copy_Fat_Pointer (Res, E);
- Chap3.Check_Composite_Match (Res_Type, Res, Expr_Type, E, Loc);
- return M2Addr (Res);
- end;
- when others =>
- Error_Kind ("translate_array_subtype_conversion", Res_Type);
- end case;
- end Translate_Array_Subtype_Conversion;
-
- function Translate_Type_Conversion
- (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir)
- return O_Enode
- is
- Res_Info : constant Type_Info_Acc := Get_Info (Res_Type);
- Res : O_Enode;
- begin
- case Get_Kind (Res_Type) is
- when Iir_Kinds_Scalar_Type_And_Subtype_Definition =>
- Res := New_Convert_Ov (Expr, Res_Info.Ortho_Type (Mode_Value));
- if Chap3.Need_Range_Check (Null_Iir, Res_Type) then
- Res := Chap3.Insert_Scalar_Check
- (Res, Null_Iir, Res_Type, Loc);
- end if;
- return Res;
- when Iir_Kinds_Array_Type_Definition =>
- if Get_Constraint_State (Res_Type) = Fully_Constrained then
- return Translate_Array_Subtype_Conversion
- (Expr, Expr_Type, Res_Type, Loc);
- else
- return Translate_Fat_Array_Type_Conversion
- (Expr, Expr_Type, Res_Type, Loc);
- end if;
- when Iir_Kind_Record_Type_Definition
- | Iir_Kind_Record_Subtype_Definition =>
- return Expr;
- when others =>
- Error_Kind ("translate_type_conversion", Res_Type);
- end case;
- end Translate_Type_Conversion;
-
- procedure Translate_Type_Conversion_Bounds
+ -- Convert the bounds of an array (and only the bounds).
+ procedure Translate_Type_Conversion_Array_Bounds
(Res : Mnode; Src : Mnode; Res_Type : Iir; Src_Type : Iir; Loc : Iir)
is
Res_Indexes : constant Iir_Flist := Get_Index_Subtype_List (Res_Type);
@@ -4597,21 +4531,18 @@ package body Trans.Chap7 is
Get_Index_Subtype_List (Res_Base_Type);
Src_Base_Indexes : constant Iir_Flist :=
Get_Index_Subtype_List (Src_Base_Type);
-
- R_El : Iir;
- S_El : Iir;
begin
-- Convert bounds.
for I in Flist_First .. Flist_Last (Src_Indexes) loop
- R_El := Get_Index_Type (Res_Indexes, I);
- S_El := Get_Index_Type (Src_Indexes, I);
declare
- Rb_Ptr : Mnode;
- Sb_Ptr : Mnode;
- Ee : O_Enode;
+ Res_Idx : constant Iir := Get_Index_Type (Res_Indexes, I);
+ Src_Idx : constant Iir := Get_Index_Type (Src_Indexes, I);
Same_Index_Type : constant Boolean :=
(Get_Index_Type (Res_Base_Indexes, I)
= Get_Index_Type (Src_Base_Indexes, I));
+ Rb_Ptr : Mnode;
+ Sb_Ptr : Mnode;
+ Ee : O_Enode;
begin
Open_Temp;
Rb_Ptr := Stabilize (Chap3.Bounds_To_Range (Res, Res_Type, I + 1));
@@ -4621,12 +4552,12 @@ package body Trans.Chap7 is
-- array in common cases).
Ee := M2E (Chap3.Range_To_Left (Sb_Ptr));
if not Same_Index_Type then
- Ee := Translate_Type_Conversion (Ee, S_El, R_El, Loc);
+ Ee := Translate_Type_Conversion (Ee, Src_Idx, Res_Idx, Loc);
end if;
New_Assign_Stmt (M2Lv (Chap3.Range_To_Left (Rb_Ptr)), Ee);
Ee := M2E (Chap3.Range_To_Right (Sb_Ptr));
if not Same_Index_Type then
- Ee := Translate_Type_Conversion (Ee, S_El, R_El, Loc);
+ Ee := Translate_Type_Conversion (Ee, Src_Idx, Res_Idx, Loc);
end if;
New_Assign_Stmt (M2Lv (Chap3.Range_To_Right (Rb_Ptr)), Ee);
-- Copy Dir and Length.
@@ -4637,7 +4568,51 @@ package body Trans.Chap7 is
Close_Temp;
end;
end loop;
- end Translate_Type_Conversion_Bounds;
+
+ -- TODO: element layout
+ -- array: same sizes, bounds: recurse; but constrained states can be
+ -- different.
+ -- record: no conversion, simply copy ?
+ declare
+ Res_El_Type : constant Iir := Get_Element_Subtype (Res_Type);
+ Src_El_Type : constant Iir := Get_Element_Subtype (Src_Type);
+ Res_El : Mnode;
+ Src_El : Mnode;
+ begin
+ if Is_Fully_Constrained_Type (Res_El_Type)
+ and then Is_Fully_Constrained_Type (Src_El_Type)
+ then
+ -- No need to convert.
+ -- TODO: still check matching length (if not same type).
+ return;
+ end if;
+
+ -- TODO: if the subtype is fully bounded, get the subtype bounds
+ -- directly (and not from the object bounds).
+ Res_El := Stabilize
+ (Chap3.Array_Bounds_To_Element_Layout (Res, Res_Type));
+ Src_El := Stabilize
+ (Chap3.Array_Bounds_To_Element_Layout (Src, Src_Type));
+
+ if Res_El_Type = Src_El_Type then
+ -- TODO: copy layout, no need to check.
+ raise Internal_Error;
+ else
+ -- TODO: copy or convert.
+ -- 1. Copy layout size
+ for K in Object_Kind_Type loop
+ New_Assign_Stmt (Chap3.Layout_To_Size (Res_El, K),
+ New_Value (Chap3.Layout_To_Size (Res_El, K)));
+ end loop;
+
+ -- 2. Recurse on bounds
+ Translate_Type_Conversion_Array_Bounds
+ (Stabilize (Chap3.Layout_To_Bounds (Res_El)),
+ Stabilize (Chap3.Layout_To_Bounds (Src_El)),
+ Res_El_Type, Src_El_Type, Loc);
+ end if;
+ end;
+ end Translate_Type_Conversion_Array_Bounds;
function Translate_Fat_Array_Type_Conversion
(Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir)
@@ -4667,7 +4642,7 @@ package body Trans.Chap7 is
New_Address (New_Obj (Bounds), Res_Info.B.Bounds_Ptr_Type));
-- Convert bounds.
- Translate_Type_Conversion_Bounds
+ Translate_Type_Conversion_Array_Bounds
(Dv2M (Bounds, Res_Info, Mode_Value,
Res_Info.B.Bounds_Type, Res_Info.B.Bounds_Ptr_Type),
Stabilize (Chap3.Get_Composite_Bounds (E)),
@@ -4677,6 +4652,69 @@ package body Trans.Chap7 is
return M2E (Res);
end Translate_Fat_Array_Type_Conversion;
+ function Translate_Array_Subtype_Conversion
+ (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir)
+ return O_Enode
+ is
+ Res_Info : constant Type_Info_Acc := Get_Info (Res_Type);
+ Expr_Info : constant Type_Info_Acc := Get_Info (Expr_Type);
+ E : Mnode;
+ begin
+ E := Stabilize (E2M (Expr, Expr_Info, Mode_Value));
+ case Res_Info.Type_Mode is
+ when Type_Mode_Bounded_Arrays =>
+ Chap3.Check_Composite_Match
+ (Res_Type, T2M (Res_Type, Mode_Value),
+ Expr_Type, E,
+ Loc);
+ return New_Convert_Ov
+ (M2Addr (Chap3.Get_Composite_Base (E)),
+ Res_Info.Ortho_Ptr_Type (Mode_Value));
+ when Type_Mode_Unbounded_Array =>
+ declare
+ Res : Mnode;
+ begin
+ Res := Create_Temp (Res_Info);
+ Copy_Fat_Pointer (Res, E);
+ Chap3.Check_Composite_Match (Res_Type, Res, Expr_Type, E, Loc);
+ return M2Addr (Res);
+ end;
+ when others =>
+ Error_Kind ("translate_array_subtype_conversion", Res_Type);
+ end case;
+ end Translate_Array_Subtype_Conversion;
+
+ function Translate_Type_Conversion
+ (Expr : O_Enode; Expr_Type : Iir; Res_Type : Iir; Loc : Iir)
+ return O_Enode
+ is
+ Res_Info : constant Type_Info_Acc := Get_Info (Res_Type);
+ Res : O_Enode;
+ begin
+ case Get_Kind (Res_Type) is
+ when Iir_Kinds_Scalar_Type_And_Subtype_Definition =>
+ Res := New_Convert_Ov (Expr, Res_Info.Ortho_Type (Mode_Value));
+ if Chap3.Need_Range_Check (Null_Iir, Res_Type) then
+ Res := Chap3.Insert_Scalar_Check
+ (Res, Null_Iir, Res_Type, Loc);
+ end if;
+ return Res;
+ when Iir_Kinds_Array_Type_Definition =>
+ if Get_Constraint_State (Res_Type) = Fully_Constrained then
+ return Translate_Array_Subtype_Conversion
+ (Expr, Expr_Type, Res_Type, Loc);
+ else
+ return Translate_Fat_Array_Type_Conversion
+ (Expr, Expr_Type, Res_Type, Loc);
+ end if;
+ when Iir_Kind_Record_Type_Definition
+ | Iir_Kind_Record_Subtype_Definition =>
+ return Expr;
+ when others =>
+ Error_Kind ("translate_type_conversion", Res_Type);
+ end case;
+ end Translate_Type_Conversion;
+
function Sig2val_Prepare_Composite
(Targ : Mnode; Targ_Type : Iir; Data : Mnode) return Mnode
is
diff --git a/src/vhdl/translate/trans-chap7.ads b/src/vhdl/translate/trans-chap7.ads
index ac69c8893..f361eb87f 100644
--- a/src/vhdl/translate/trans-chap7.ads
+++ b/src/vhdl/translate/trans-chap7.ads
@@ -87,7 +87,7 @@ package Trans.Chap7 is
(Res : in out Mnode; Expr : Mnode);
-- Convert bounds SRC (of type SRC_TYPE) to RES (of type RES_TYPE).
- procedure Translate_Type_Conversion_Bounds
+ procedure Translate_Type_Conversion_Array_Bounds
(Res : Mnode; Src : Mnode; Res_Type : Iir; Src_Type : Iir; Loc : Iir);
-- Convert range EXPR into ortho tree.