diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-08-24 20:59:30 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-08-25 18:13:52 +0200 |
commit | 763ad94d204baa585c688df959fcecef2f76b7c7 (patch) | |
tree | e3e112c1eb9b62113995517ba83839721fdf611b | |
parent | 47fb320579b9ce491f1c1caf18f85a601a8b21bb (diff) | |
download | ghdl-763ad94d204baa585c688df959fcecef2f76b7c7.tar.gz ghdl-763ad94d204baa585c688df959fcecef2f76b7c7.tar.bz2 ghdl-763ad94d204baa585c688df959fcecef2f76b7c7.zip |
vhdl-evaluation: make eval_dyadic_bit_array_operator more generic.
Handle any form of static expressions. Fix #1429
-rw-r--r-- | src/vhdl/vhdl-evaluation.adb | 113 |
1 files changed, 71 insertions, 42 deletions
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. |