aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-08-24 20:59:30 +0200
committerTristan Gingold <tgingold@free.fr>2020-08-25 18:13:52 +0200
commit763ad94d204baa585c688df959fcecef2f76b7c7 (patch)
treee3e112c1eb9b62113995517ba83839721fdf611b /src
parent47fb320579b9ce491f1c1caf18f85a601a8b21bb (diff)
downloadghdl-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
Diffstat (limited to 'src')
-rw-r--r--src/vhdl/vhdl-evaluation.adb113
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.