From 763ad94d204baa585c688df959fcecef2f76b7c7 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 24 Aug 2020 20:59:30 +0200 Subject: vhdl-evaluation: make eval_dyadic_bit_array_operator more generic. Handle any form of static expressions. Fix #1429 --- src/vhdl/vhdl-evaluation.adb | 113 +++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/vhdl/vhdl-evaluation.adb b/src/vhdl/vhdl-evaluation.adb index 65fa9e6ec..9206db678 100644 --- a/src/vhdl/vhdl-evaluation.adb +++ b/src/vhdl/vhdl-evaluation.adb @@ -783,110 +783,139 @@ package body Vhdl.Evaluation is function Eval_Dyadic_Bit_Array_Operator (Expr : Iir; Left, Right : Iir; - Func : Iir_Predefined_Dyadic_TF_Array_Functions) - return Iir + Func : Iir_Predefined_Dyadic_TF_Array_Functions) return Iir is - use Str_Table; - L_Str : constant String8_Id := Get_String8_Id (Left); - R_Str : constant String8_Id := Get_String8_Id (Right); - Len : Nat32; - Id : String8_Id; + Expr_Type : constant Iir := Get_Type (Expr); + El_Type : constant Iir := + Get_Base_Type (Get_Element_Subtype (Expr_Type)); + Enum_List : constant Iir_Flist := Get_Enumeration_Literal_List (El_Type); + Cst_0 : constant Iir := Get_Nth_Element (Enum_List, 0); + Cst_1 : constant Iir := Get_Nth_Element (Enum_List, 1); + Left_Val, Right_Val : Iir; + R_List, L_List : Iir_Flist; + Len : Natural; Res : Iir; + Res_List : Iir_Flist; + El : Iir; begin - Len := Get_String_Length (Left); - if Len /= Get_String_Length (Right) then + Left_Val := Eval_String_Literal (Left); + Right_Val := Eval_String_Literal (Right); + + L_List := Get_Simple_Aggregate_List (Left_Val); + R_List := Get_Simple_Aggregate_List (Right_Val); + Len := Get_Nbr_Elements (L_List); + + if Len /= Get_Nbr_Elements (R_List) then Warning_Msg_Sem (Warnid_Runtime_Error, +Expr, "length of left and right operands mismatch"); - return Build_Overflow (Expr); + Res := Build_Overflow (Expr); else - Id := Create_String8; + Res_List := Create_Iir_Flist (Len); + case Func is when Iir_Predefined_TF_Array_And => - for I in 1 .. Len loop - case Element_String8 (L_Str, I) is + for I in 0 .. Len - 1 loop + El := Get_Nth_Element (L_List, I); + case Get_Enum_Pos (El) is when 0 => - Append_String8 (0); + null; when 1 => - Append_String8 (Element_String8 (R_Str, I)); + El := Get_Nth_Element (R_List, I); when others => raise Internal_Error; end case; + Set_Nth_Element (Res_List, I, El); end loop; when Iir_Predefined_TF_Array_Nand => - for I in 1 .. Len loop - case Element_String8 (L_Str, I) is + for I in 0 .. Len - 1 loop + El := Get_Nth_Element (L_List, I); + case Get_Enum_Pos (El) is when 0 => - Append_String8 (1); + El := Cst_1; when 1 => - case Element_String8 (R_Str, I) is + El := Get_Nth_Element (R_List, I); + case Get_Enum_Pos (El) is when 0 => - Append_String8 (1); + El := Cst_1; when 1 => - Append_String8 (0); + El := Cst_0; when others => raise Internal_Error; end case; when others => raise Internal_Error; end case; + Set_Nth_Element (Res_List, I, El); end loop; when Iir_Predefined_TF_Array_Or => - for I in 1 .. Len loop - case Element_String8 (L_Str, I) is + for I in 0 .. Len - 1 loop + El := Get_Nth_Element (L_List, I); + case Get_Enum_Pos (El) is when 1 => - Append_String8 (1); + null; when 0 => - Append_String8 (Element_String8 (R_Str, I)); + El := Get_Nth_Element (R_List, I); when others => raise Internal_Error; end case; + Set_Nth_Element (Res_List, I, El); end loop; when Iir_Predefined_TF_Array_Nor => - for I in 1 .. Len loop - case Element_String8 (L_Str, I) is + for I in 0 .. Len - 1 loop + El := Get_Nth_Element (L_List, I); + case Get_Enum_Pos (El) is when 1 => - Append_String8 (0); + El := Cst_0; when 0 => - case Element_String8 (R_Str, I) is + El := Get_Nth_Element (R_List, I); + case Get_Enum_Pos (El) is when 0 => - Append_String8 (1); + El := Cst_1; when 1 => - Append_String8 (0); + El := Cst_0; when others => raise Internal_Error; end case; when others => raise Internal_Error; end case; + Set_Nth_Element (Res_List, I, El); end loop; when Iir_Predefined_TF_Array_Xor => - for I in 1 .. Len loop - case Element_String8 (L_Str, I) is + for I in 0 .. Len - 1 loop + El := Get_Nth_Element (L_List, I); + case Get_Enum_Pos (El) is when 1 => - case Element_String8 (R_Str, I) is + El := Get_Nth_Element (R_List, I); + case Get_Enum_Pos (El) is when 0 => - Append_String8 (1); + El := Cst_1; when 1 => - Append_String8 (0); + El := Cst_0; when others => raise Internal_Error; end case; when 0 => - Append_String8 (Element_String8 (R_Str, I)); + El := Get_Nth_Element (R_List, I); when others => raise Internal_Error; end case; + Set_Nth_Element (Res_List, I, El); end loop; when others => Error_Internal (Expr, "eval_dyadic_bit_array_functions: " & - Iir_Predefined_Functions'Image (Func)); + Iir_Predefined_Functions'Image (Func)); end case; - Res := Build_String (Id, Len, Expr); - -- The unconstrained type is replaced by the constrained one. - Set_Type (Res, Get_Type (Left)); - return Res; + Res := Build_Simple_Aggregate (Res_List, Expr, Expr_Type); end if; + + Free_Eval_Static_Expr (Left_Val, Left); + Free_Eval_Static_Expr (Right_Val, Right); + + -- The unconstrained type is replaced by the constrained one. + Set_Type (Res, Get_Type (Left)); + return Res; end Eval_Dyadic_Bit_Array_Operator; -- Return TRUE if VAL /= 0. -- cgit v1.2.3