diff options
Diffstat (limited to 'src/vhdl/evaluation.adb')
-rw-r--r-- | src/vhdl/evaluation.adb | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/src/vhdl/evaluation.adb b/src/vhdl/evaluation.adb index 3e6cdc7f4..0c1a91444 100644 --- a/src/vhdl/evaluation.adb +++ b/src/vhdl/evaluation.adb @@ -159,7 +159,7 @@ package body Evaluation is -- Build a simple aggregate composed of EL_LIST from ORIGIN. STYPE is the -- type of the aggregate. DEF_TYPE should be either Null_Iir or STYPE. It -- is set only when a new subtype has been created for the aggregate. - function Build_Simple_Aggregate (El_List : Iir_List; + function Build_Simple_Aggregate (El_List : Iir_Flist; Origin : Iir; Stype : Iir; Def_Type : Iir := Null_Iir) @@ -452,11 +452,11 @@ package body Evaluation is -- Free the result RES of Eval_String_Literal called with ORIG, if created. procedure Free_Eval_String_Literal (Res : Iir; Orig : Iir) is - L : Iir_List; + L : Iir_Flist; begin if Res /= Orig then L := Get_Simple_Aggregate_List (Res); - Destroy_Iir_List (L); + Destroy_Iir_Flist (L); Free_Iir (Res); end if; end Free_Eval_String_Literal; @@ -471,15 +471,15 @@ package body Evaluation is Len : constant Nat32 := Get_String_Length (Str); Id : constant String8_Id := Get_String8_Id (Str); - List : Iir_List; + List : Iir_Flist; Lit : Iir; begin - List := Create_Iir_List; + List := Create_Iir_Flist (Natural (Len)); for I in 1 .. Len loop Lit := Get_Nth_Element (Literal_List, Natural (Str_Table.Element_String8 (Id, I))); - Append_Element (List, Lit); + Set_Nth_Element (List, Natural (I - 1), Lit); end loop; return Build_Simple_Aggregate (List, Str, Get_Type (Str)); end String_Literal8_To_Simple_Aggregate; @@ -566,7 +566,7 @@ package body Evaluation is Len : constant Iir_Int64 := Eval_Discrete_Range_Length (Index_Range); Assocs : constant Iir := Get_Association_Choices_Chain (Aggr); Vect : Iir_Array (0 .. Integer (Len - 1)); - List : Iir_List; + List : Iir_Flist; Assoc : Iir; Expr : Iir; begin @@ -586,11 +586,11 @@ package body Evaluation is Build_Array_Choices_Vector (Vect, Index_Range, Assocs); - List := Create_Iir_List; + List := Create_Iir_Flist (Natural (Len)); if Len > 0 then -- Workaround GNAT GPL2014 compiler bug. for I in Vect'Range loop - Append_Element (List, Get_Associated_Expr (Vect (I))); + Set_Nth_Element (List, I, Get_Associated_Expr (Vect (I))); end loop; end if; @@ -657,18 +657,17 @@ package body Evaluation is when Iir_Predefined_TF_Array_Not => declare Lit_Val : Iir; - O_List : Iir_List; - R_List : Iir_List; + O_List : Iir_Flist; + R_List : Iir_Flist; El : Iir; Lit : Iir; begin Lit_Val := Eval_String_Literal (Operand); O_List := Get_Simple_Aggregate_List (Lit_Val); - R_List := Create_Iir_List; + R_List := Create_Iir_Flist (Get_Nbr_Elements (O_List)); - for I in Natural loop + for I in Flist_First .. Flist_Last (O_List) loop El := Get_Nth_Element (O_List, I); - exit when El = Null_Iir; case Get_Enum_Pos (El) is when 0 => Lit := Bit_1; @@ -677,7 +676,7 @@ package body Evaluation is when others => raise Internal_Error; end case; - Append_Element (R_List, Lit); + Set_Nth_Element (R_List, I, Lit); end loop; Free_Eval_String_Literal (Lit_Val, Operand); return Build_Simple_Aggregate @@ -694,7 +693,7 @@ package body Evaluation is -- LRM08 5.3.2.4 Predefined operations on array types declare Saggr : Iir; - Lits : Iir_List; + Lits : Iir_Flist; Res : Iir; El : Iir; Cmp : Compare_Type; @@ -718,9 +717,8 @@ package body Evaluation is end; else Res := Get_Nth_Element (Lits, 0); - for I in Positive loop + for I in Flist_First .. Flist_Last (Lits) loop El := Get_Nth_Element (Lits, I); - exit when El = Null_Iir; Cmp := Eval_Scalar_Compare (El, Res); case Iir_Predefined_Vector_Minmax (Func) is when Iir_Predefined_Vector_Minimum => @@ -876,17 +874,14 @@ package body Evaluation is (Left, Right : Iir; Origin : Iir; Func : Iir_Predefined_Shift_Functions) return Iir is - Count : Iir_Int64; + Count : constant Iir_Int64 := Get_Value (Right); + Arr_List : constant Iir_Flist := Get_Simple_Aggregate_List (Left); + Len : constant Natural := Get_Nbr_Elements (Arr_List); Cnt : Natural; - Len : Natural; - Arr_List : Iir_List; - Res_List : Iir_List; + Res_List : Iir_Flist; Dir_Left : Boolean; E : Iir; begin - Count := Get_Value (Right); - Arr_List := Get_Simple_Aggregate_List (Left); - Len := Get_Nbr_Elements (Arr_List); -- LRM93 7.2.3 -- That is, if R is 0 or if L is a null array, the return value is L. if Count = 0 or Len = 0 then @@ -934,7 +929,7 @@ package body Evaluation is end if; end case; - Res_List := Create_Iir_List; + Res_List := Create_Iir_Flist (Len); case Func is when Iir_Predefined_Array_Sll @@ -944,32 +939,32 @@ package body Evaluation is if Dir_Left then if Cnt < Len then for I in Cnt .. Len - 1 loop - Append_Element - (Res_List, Get_Nth_Element (Arr_List, I)); + Set_Nth_Element + (Res_List, I - Cnt, Get_Nth_Element (Arr_List, I)); end loop; else Cnt := Len; end if; for I in 0 .. Cnt - 1 loop - Append_Element (Res_List, E); + Set_Nth_Element (Res_List, Len - Cnt + I, E); end loop; else if Cnt > Len then Cnt := Len; end if; for I in 0 .. Cnt - 1 loop - Append_Element (Res_List, E); + Set_Nth_Element (Res_List, I, E); end loop; for I in Cnt .. Len - 1 loop - Append_Element - (Res_List, Get_Nth_Element (Arr_List, I - Cnt)); + Set_Nth_Element + (Res_List, I, Get_Nth_Element (Arr_List, I - Cnt)); end loop; end if; when Iir_Predefined_Array_Rol | Iir_Predefined_Array_Ror => for I in 1 .. Len loop - Append_Element - (Res_List, Get_Nth_Element (Arr_List, Cnt)); + Set_Nth_Element + (Res_List, I - 1, Get_Nth_Element (Arr_List, Cnt)); Cnt := Cnt + 1; if Cnt = Len then Cnt := 0; @@ -984,29 +979,50 @@ package body Evaluation is (Left, Right : Iir; Orig : Iir; Func : Iir_Predefined_Concat_Functions) return Iir is - Res_List : Iir_List; - L : Natural; + Res_List : Iir_Flist; + Res_Len : Natural; Res_Type : Iir; Origin_Type : Iir; Left_Aggr, Right_Aggr : Iir; - Left_List, Right_List : Iir_List; - Left_Len : Natural; + Left_List, Right_List : Iir_Flist; + Left_Len, Right_Len : Natural; begin - Res_List := Create_Iir_List; - -- Do the concatenation. + -- Compute length of the result. -- Left: case Func is when Iir_Predefined_Element_Array_Concat | Iir_Predefined_Element_Element_Concat => - Append_Element (Res_List, Left); Left_Len := 1; when Iir_Predefined_Array_Element_Concat | Iir_Predefined_Array_Array_Concat => Left_Aggr := Eval_String_Literal (Left); Left_List := Get_Simple_Aggregate_List (Left_Aggr); Left_Len := Get_Nbr_Elements (Left_List); + end case; + -- Right: + case Func is + when Iir_Predefined_Array_Element_Concat + | Iir_Predefined_Element_Element_Concat => + Right_Len := 1; + when Iir_Predefined_Element_Array_Concat + | Iir_Predefined_Array_Array_Concat => + Right_Aggr := Eval_String_Literal (Right); + Right_List := Get_Simple_Aggregate_List (Right_Aggr); + Right_Len := Get_Nbr_Elements (Right_List); + end case; + + Res_Len := Left_Len + Right_Len; + Res_List := Create_Iir_Flist (Res_Len); + -- Do the concatenation. + -- Left: + case Func is + when Iir_Predefined_Element_Array_Concat + | Iir_Predefined_Element_Element_Concat => + Set_Nth_Element (Res_List, 0, Left); + when Iir_Predefined_Array_Element_Concat + | Iir_Predefined_Array_Array_Concat => for I in 0 .. Left_Len - 1 loop - Append_Element (Res_List, Get_Nth_Element (Left_List, I)); + Set_Nth_Element (Res_List, I, Get_Nth_Element (Left_List, I)); end loop; Free_Eval_String_Literal (Left_Aggr, Left); end case; @@ -1014,18 +1030,15 @@ package body Evaluation is case Func is when Iir_Predefined_Array_Element_Concat | Iir_Predefined_Element_Element_Concat => - Append_Element (Res_List, Right); + Set_Nth_Element (Res_List, Left_Len, Right); when Iir_Predefined_Element_Array_Concat | Iir_Predefined_Array_Array_Concat => - Right_Aggr := Eval_String_Literal (Right); - Right_List := Get_Simple_Aggregate_List (Right_Aggr); - L := Get_Nbr_Elements (Right_List); - for I in 0 .. L - 1 loop - Append_Element (Res_List, Get_Nth_Element (Right_List, I)); + for I in 0 .. Right_Len - 1 loop + Set_Nth_Element + (Res_List, Left_Len + I, Get_Nth_Element (Right_List, I)); end loop; Free_Eval_String_Literal (Right_Aggr, Right); end case; - L := Get_Nbr_Elements (Res_List); -- Compute subtype... Origin_Type := Get_Type (Orig); @@ -1074,7 +1087,7 @@ package body Evaluation is Set_Left_Limit (A_Range, Get_Left_Limit (Left_Range)); Set_Direction (A_Range, Get_Direction (Left_Range)); Location_Copy (A_Range, Orig); - Set_Right_Limit_By_Length (A_Range, Iir_Int64 (L)); + Set_Right_Limit_By_Length (A_Range, Iir_Int64 (Res_Len)); Index_Type := Create_Range_Subtype_From_Type (Left_Index, Get_Location (Orig)); Set_Range_Constraint (Index_Type, A_Range); @@ -1089,7 +1102,7 @@ package body Evaluation is -- concatenation is the direction of S, and the left bound of the -- result is S'LEFT. Res_Type := Create_Unidim_Array_By_Length - (Origin_Type, Iir_Int64 (L), Orig); + (Origin_Type, Iir_Int64 (Res_Len), Orig); end if; end if; -- FIXME: this is not necessarily a string, it may be an aggregate if @@ -1209,7 +1222,7 @@ package body Evaluation is -- General case. declare Left_Val, Right_Val : Iir; - R_List, L_List : Iir_List; + R_List, L_List : Iir_Flist; R_Len, L_Len : Natural; P : Natural; Res : Compare_Type; @@ -3554,7 +3567,8 @@ package body Evaluation is case Get_Kind (Expr) is when Iir_Kind_Simple_Aggregate => declare - List : constant Iir_List := Get_Simple_Aggregate_List (Expr); + List : constant Iir_Flist := + Get_Simple_Aggregate_List (Expr); begin return Str_Info'(Is_String => False, Len => Nat32 (Get_Nbr_Elements (List)), |