1--  Interpreted simulation
2--  Copyright (C) 2014 Tristan Gingold
3--
4--  This program is free software: you can redistribute it and/or modify
5--  it under the terms of the GNU General Public License as published by
6--  the Free Software Foundation, either version 2 of the License, or
7--  (at your option) any later version.
8--
9--  This program is distributed in the hope that it will be useful,
10--  but WITHOUT ANY WARRANTY; without even the implied warranty of
11--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12--  GNU General Public License for more details.
13--
14--  You should have received a copy of the GNU General Public License
15--  along with this program.  If not, see <gnu.org/licenses>.
16
17with System;
18with Ada.Unchecked_Conversion;
19with Simple_IO; use Simple_IO;
20with Types; use Types;
21with Grt.Types; use Grt.Types;
22with Flags; use Flags;
23with Vhdl.Errors; use Vhdl.Errors;
24with Vhdl.Std_Package;
25with Vhdl.Evaluation;
26with Vhdl.Utils; use Vhdl.Utils;
27with Name_Table;
28with Simul.File_Operation;
29with Simul.Debugger; use Simul.Debugger;
30with Std_Names;
31with Str_Table;
32with Files_Map;
33with Vhdl.Nodes_Utils; use Vhdl.Nodes_Utils;
34with Simul.Simulation; use Simul.Simulation;
35with Grt.Astdio.Vhdl;
36with Grt.Stdio;
37with Grt.Options;
38with Grt.Vstrings;
39with Grt.To_Strings;
40with Simul.Grt_Interface;
41with Grt.Values;
42with Grt.Errors;
43with Grt.Std_Logic_1164;
44with Grt.Lib;
45with Grt.Strings;
46with Vhdl.Sem_Inst;
47
48package body Simul.Execution is
49
50   function Execute_Function_Call
51     (Block: Block_Instance_Acc; Expr: Iir; Imp : Iir)
52     return Iir_Value_Literal_Acc;
53
54   procedure Finish_Sequential_Statements
55     (Proc : Process_State_Acc; Complex_Stmt : Iir);
56   procedure Init_Sequential_Statements
57     (Proc : Process_State_Acc; Complex_Stmt : Iir);
58   procedure Update_Next_Statement (Proc : Process_State_Acc);
59
60   -- Display a message when an assertion has failed.
61   procedure Execute_Failed_Assertion (Msg : String;
62                                       Report : String;
63                                       Severity : Natural;
64                                       Stmt: Iir);
65
66   function Get_Instance_By_Scope
67     (Instance: Block_Instance_Acc; Scope: Sim_Info_Acc)
68     return Block_Instance_Acc is
69   begin
70      case Scope.Kind is
71         when Kind_Block
72           | Kind_Frame
73           | Kind_Process =>
74            declare
75               Current : Block_Instance_Acc;
76            begin
77               Current := Instance;
78               while Current /= null loop
79                  if Current.Block_Scope = Scope then
80                     return Current;
81                  end if;
82                  Current := Current.Up_Block;
83               end loop;
84               raise Internal_Error;
85            end;
86         when Kind_Protected =>
87            declare
88               Current : Block_Instance_Acc;
89            begin
90               Current := Instance;
91               while Current /= null loop
92                  if Current.Block_Scope = Scope
93                    or Current.Uninst_Scope = Scope
94                  then
95                     return Current;
96                  end if;
97                  Current := Current.Up_Block;
98               end loop;
99               raise Internal_Error;
100            end;
101         when Kind_Package =>
102            if Scope.Pkg_Parent = null then
103               --  This is a scope for an uninstantiated package.
104               declare
105                  Current : Block_Instance_Acc;
106               begin
107                  Current := Instance;
108                  while Current /= null loop
109                     if Current.Uninst_Scope = Scope then
110                        return Current;
111                     end if;
112                     Current := Current.Up_Block;
113                  end loop;
114                  raise Internal_Error;
115               end;
116            else
117               --  Instantiated package.
118               declare
119                  Parent : Block_Instance_Acc;
120               begin
121                  Parent := Get_Instance_By_Scope (Instance, Scope.Pkg_Parent);
122                  return Parent.Objects (Scope.Pkg_Slot).Instance;
123               end;
124            end if;
125         when others =>
126            raise Internal_Error;
127      end case;
128   end Get_Instance_By_Scope;
129
130   function Get_Instance_Object (Instance: Block_Instance_Acc; Obj : Iir)
131                                return Iir_Value_Literal_Acc
132   is
133      Info : constant Sim_Info_Acc := Get_Info (Obj);
134      Obj_Inst : Block_Instance_Acc;
135   begin
136      Obj_Inst := Get_Instance_By_Scope (Instance, Info.Obj_Scope);
137      return Obj_Inst.Objects (Info.Slot);
138   end Get_Instance_Object;
139
140   function Get_Info_For_Scope (Scope : Iir) return Sim_Info_Acc is
141   begin
142      --  The info for an architecture is in fact the entity.
143      if Get_Kind (Scope) = Iir_Kind_Architecture_Body then
144         return Get_Info (Get_Entity (Scope));
145      else
146         return Get_Info (Scope);
147      end if;
148   end Get_Info_For_Scope;
149
150   procedure Create_Right_Bound_From_Length
151     (Bounds : Iir_Value_Literal_Acc; Len : Iir_Index32) is
152   begin
153      pragma Assert (Bounds.Right = null);
154
155      case Bounds.Left.Kind is
156         when Iir_Value_E32 =>
157            declare
158               R : Ghdl_E32;
159            begin
160               case Bounds.Dir is
161                  when Dir_To =>
162                     R := Bounds.Left.E32 + Ghdl_E32 (Len - 1);
163                  when Dir_Downto =>
164                     R := Bounds.Left.E32 - Ghdl_E32 (Len - 1);
165               end case;
166               Bounds.Right := Create_E32_Value (R);
167            end;
168         when Iir_Value_I64 =>
169            declare
170               R : Ghdl_I64;
171            begin
172               case Bounds.Dir is
173                  when Dir_To =>
174                     R := Bounds.Left.I64 + Ghdl_I64 (Len - 1);
175                  when Dir_Downto =>
176                     R := Bounds.Left.I64 - Ghdl_I64 (Len - 1);
177               end case;
178               Bounds.Right := Create_I64_Value (R);
179            end;
180         when others =>
181            raise Internal_Error;
182      end case;
183   end Create_Right_Bound_From_Length;
184
185   function Create_Bounds_From_Length (Block : Block_Instance_Acc;
186                                       Atype : Iir;
187                                       Len : Iir_Index32)
188                                      return Iir_Value_Literal_Acc
189   is
190      Res : Iir_Value_Literal_Acc;
191      Index_Bounds : Iir_Value_Literal_Acc;
192   begin
193      Index_Bounds := Execute_Bounds (Block, Atype);
194
195      Res := Create_Range_Value (Left => Index_Bounds.Left,
196                                 Right => null,
197                                 Dir => Index_Bounds.Dir,
198                                 Length => Len);
199
200      if Len = 0 then
201         --  Special case.
202         Res.Right := Res.Left;
203         case Res.Left.Kind is
204            when Iir_Value_I64 =>
205               case Index_Bounds.Dir is
206                  when Dir_To =>
207                     Res.Left := Create_I64_Value (Res.Right.I64 + 1);
208                  when Dir_Downto =>
209                     Res.Left := Create_I64_Value (Res.Right.I64 - 1);
210               end case;
211            when others =>
212               raise Internal_Error;
213         end case;
214      else
215         Create_Right_Bound_From_Length (Res, Len);
216      end if;
217      return Res;
218   end Create_Bounds_From_Length;
219
220   function Execute_High_Limit (Bounds : Iir_Value_Literal_Acc)
221                                return Iir_Value_Literal_Acc is
222   begin
223      if Bounds.Dir = Dir_To then
224         return Bounds.Right;
225      else
226         return Bounds.Left;
227      end if;
228   end Execute_High_Limit;
229
230   function Execute_Low_Limit (Bounds : Iir_Value_Literal_Acc)
231                               return Iir_Value_Literal_Acc is
232   begin
233      if Bounds.Dir = Dir_To then
234         return Bounds.Left;
235      else
236         return Bounds.Right;
237      end if;
238   end Execute_Low_Limit;
239
240   function Execute_Left_Limit (Bounds : Iir_Value_Literal_Acc)
241                                return Iir_Value_Literal_Acc is
242   begin
243      return Bounds.Left;
244   end Execute_Left_Limit;
245
246   function Execute_Right_Limit (Bounds : Iir_Value_Literal_Acc)
247                                 return Iir_Value_Literal_Acc is
248   begin
249      return Bounds.Right;
250   end Execute_Right_Limit;
251
252   function Execute_Length (Bounds : Iir_Value_Literal_Acc)
253                           return Iir_Value_Literal_Acc is
254   begin
255      return Create_I64_Value (Ghdl_I64 (Bounds.Length));
256   end Execute_Length;
257
258   function Create_Enum_Value (Pos : Natural; Etype : Iir)
259                              return Iir_Value_Literal_Acc
260   is
261      Base_Type : constant Iir := Get_Base_Type (Etype);
262      Kind : constant Kind_Enum_Types := Get_Info (Base_Type).Kind;
263   begin
264      case Kind is
265         when Kind_E8_Type
266           | Kind_Log_Type =>
267            return Create_E8_Value (Ghdl_E8 (Pos));
268         when Kind_E32_Type =>
269            return Create_E32_Value (Ghdl_E32 (Pos));
270         when Kind_Bit_Type =>
271            return Create_B1_Value (Ghdl_B1'Val (Pos));
272      end case;
273   end Create_Enum_Value;
274
275   function String_To_Iir_Value (Str : String) return Iir_Value_Literal_Acc
276   is
277      Res : Iir_Value_Literal_Acc;
278   begin
279      Res := Create_Array_Value (Str'Length, 1);
280      Res.Bounds.D (1) := Create_Range_Value
281        (Create_I64_Value (1),
282         Create_I64_Value (Str'Length),
283         Dir_To);
284      for I in Str'Range loop
285         Res.Val_Array.V (1 + Iir_Index32 (I - Str'First)) :=
286           Create_E8_Value (Character'Pos (Str (I)));
287      end loop;
288      return Res;
289   end String_To_Iir_Value;
290
291   function Execute_Image_Attribute (Val : Iir_Value_Literal_Acc;
292                                     Expr_Type : Iir)
293                                    return String
294   is
295   begin
296      case Get_Kind (Expr_Type) is
297         when Iir_Kind_Floating_Type_Definition
298           | Iir_Kind_Floating_Subtype_Definition =>
299            declare
300               Str : String (1 .. 24);
301               Last : Natural;
302            begin
303               Grt.To_Strings.To_String (Str, Last, Val.F64);
304               return Str (Str'First .. Last);
305            end;
306         when Iir_Kind_Integer_Type_Definition
307           | Iir_Kind_Integer_Subtype_Definition =>
308            declare
309               Str : String (1 .. 21);
310               First : Natural;
311            begin
312               Grt.To_Strings.To_String (Str, First, Val.I64);
313               return Str (First .. Str'Last);
314            end;
315         when Iir_Kind_Enumeration_Type_Definition
316           | Iir_Kind_Enumeration_Subtype_Definition =>
317            declare
318               Lits : constant Iir_Flist :=
319                 Get_Enumeration_Literal_List (Get_Base_Type (Expr_Type));
320               Pos : Natural;
321            begin
322               case Iir_Value_Enums (Val.Kind) is
323                  when Iir_Value_B1 =>
324                     Pos := Ghdl_B1'Pos (Val.B1);
325                  when Iir_Value_E8 =>
326                     Pos := Ghdl_E8'Pos (Val.E8);
327                  when Iir_Value_E32 =>
328                     Pos := Ghdl_E32'Pos (Val.E32);
329               end case;
330               return Name_Table.Image
331                 (Get_Identifier (Get_Nth_Element (Lits, Pos)));
332            end;
333         when Iir_Kind_Physical_Type_Definition
334           | Iir_Kind_Physical_Subtype_Definition =>
335            declare
336               Str : String (1 .. 21);
337               First : Natural;
338               Id : constant Name_Id :=
339                 Get_Identifier (Get_Primary_Unit (Get_Base_Type (Expr_Type)));
340            begin
341               Grt.To_Strings.To_String (Str, First, Val.I64);
342               return Str (First .. Str'Last) & ' ' & Name_Table.Image (Id);
343            end;
344         when others =>
345            Error_Kind ("execute_image_attribute", Expr_Type);
346      end case;
347   end Execute_Image_Attribute;
348
349   function Execute_Image_Attribute (Block: Block_Instance_Acc; Expr: Iir)
350                                    return Iir_Value_Literal_Acc
351   is
352      Val : Iir_Value_Literal_Acc;
353      Attr_Type : constant Iir := Get_Type (Get_Prefix (Expr));
354   begin
355      Val := Execute_Expression (Block, Get_Parameter (Expr));
356      return String_To_Iir_Value
357        (Execute_Image_Attribute (Val, Attr_Type));
358   end Execute_Image_Attribute;
359
360   function Execute_Path_Instance_Name_Attribute
361     (Block : Block_Instance_Acc; Attr : Iir) return Iir_Value_Literal_Acc
362   is
363      use Vhdl.Evaluation;
364      use Grt.Vstrings;
365      use Name_Table;
366
367      Name : constant Path_Instance_Name_Type :=
368        Get_Path_Instance_Name_Suffix (Attr);
369      Instance : Block_Instance_Acc;
370      Rstr : Rstring;
371      Is_Instance : constant Boolean :=
372        Get_Kind (Attr) = Iir_Kind_Instance_Name_Attribute;
373   begin
374      if Name.Path_Instance = Null_Iir then
375         return String_To_Iir_Value (Name.Suffix);
376      end if;
377
378      Instance := Get_Instance_By_Scope
379        (Block, Get_Info_For_Scope (Name.Path_Instance));
380
381      loop
382         case Get_Kind (Instance.Label) is
383            when Iir_Kind_Entity_Declaration =>
384               if Instance.Parent = null then
385                  Prepend (Rstr, Image (Get_Identifier (Instance.Label)));
386                  exit;
387               end if;
388            when Iir_Kind_Architecture_Body =>
389               if Is_Instance then
390                  Prepend (Rstr, ')');
391                  Prepend (Rstr, Image (Get_Identifier (Instance.Label)));
392                  Prepend (Rstr, '(');
393               end if;
394
395               if Is_Instance or else Instance.Parent = null then
396                  Prepend
397                    (Rstr,
398                     Image (Get_Identifier (Get_Entity (Instance.Label))));
399               end if;
400               if Instance.Parent = null then
401                  Prepend (Rstr, ':');
402                  exit;
403               else
404                  Instance := Instance.Parent;
405               end if;
406            when Iir_Kind_Block_Statement =>
407               Prepend (Rstr, Image (Get_Label (Instance.Label)));
408               Prepend (Rstr, ':');
409               Instance := Instance.Parent;
410            when Iir_Kind_Iterator_Declaration =>
411               declare
412                  Val : Iir_Value_Literal_Acc;
413               begin
414                  Val := Execute_Name (Instance, Instance.Label);
415                  Prepend (Rstr, ')');
416                  Prepend (Rstr, Execute_Image_Attribute
417                             (Val, Get_Type (Instance.Label)));
418                  Prepend (Rstr, '(');
419               end;
420               Instance := Instance.Parent;
421            when Iir_Kind_Generate_Statement_Body =>
422               Prepend (Rstr, Image (Get_Label (Get_Parent (Instance.Label))));
423               Prepend (Rstr, ':');
424               Instance := Instance.Parent;
425            when Iir_Kind_Component_Instantiation_Statement =>
426               if Is_Instance then
427                  Prepend (Rstr, '@');
428               end if;
429               Prepend (Rstr, Image (Get_Label (Instance.Label)));
430               Prepend (Rstr, ':');
431               Instance := Instance.Parent;
432            when others =>
433               Error_Kind ("Execute_Path_Instance_Name_Attribute",
434                           Instance.Label);
435         end case;
436      end loop;
437      declare
438         Str1 : String (1 .. Length (Rstr));
439         Len1 : Natural;
440      begin
441         Copy (Rstr, Str1, Len1);
442         Free (Rstr);
443         return String_To_Iir_Value (Str1 & ':' & Name.Suffix);
444      end;
445   end Execute_Path_Instance_Name_Attribute;
446
447   function Execute_Shift_Operator (Left : Iir_Value_Literal_Acc;
448                                    Count : Ghdl_I64;
449                                    Expr : Iir)
450                                   return Iir_Value_Literal_Acc
451   is
452      Func : constant Iir_Predefined_Shift_Functions :=
453        Get_Implicit_Definition (Get_Implementation (Expr));
454      Cnt : Iir_Index32;
455      Len : constant Iir_Index32 := Left.Bounds.D (1).Length;
456      Dir_Left : Boolean;
457      P : Iir_Index32;
458      Res : Iir_Value_Literal_Acc;
459      E : Iir_Value_Literal_Acc;
460   begin
461      --  LRM93 7.2.3
462      --  That is, if R is 0 or if L is a null array, the return value is L.
463      if Count = 0 or else Len = 0 then
464         return Left;
465      end if;
466
467      case Func is
468         when Iir_Predefined_Array_Sll
469           | Iir_Predefined_Array_Sla
470           | Iir_Predefined_Array_Rol =>
471            Dir_Left := True;
472         when Iir_Predefined_Array_Srl
473           | Iir_Predefined_Array_Sra
474           | Iir_Predefined_Array_Ror =>
475            Dir_Left := False;
476      end case;
477      if Count < 0 then
478         Cnt := Iir_Index32 (-Count);
479         Dir_Left := not Dir_Left;
480      else
481         Cnt := Iir_Index32 (Count);
482      end if;
483
484      case Func is
485         when Iir_Predefined_Array_Sll
486           | Iir_Predefined_Array_Srl =>
487            E := Create_Enum_Value
488              (0, Get_Element_Subtype (Get_Base_Type (Get_Type (Expr))));
489         when Iir_Predefined_Array_Sla
490           | Iir_Predefined_Array_Sra =>
491            if Dir_Left then
492               E := Left.Val_Array.V (Len);
493            else
494               E := Left.Val_Array.V (1);
495            end if;
496         when Iir_Predefined_Array_Rol
497           | Iir_Predefined_Array_Ror =>
498            Cnt := Cnt mod Len;
499            if not Dir_Left then
500               Cnt := (Len - Cnt) mod Len;
501            end if;
502      end case;
503
504      Res := Create_Array_Value (1);
505      Res.Bounds.D (1) := Left.Bounds.D (1);
506      Create_Array_Data (Res, Len);
507      P := 1;
508
509      case Func is
510         when Iir_Predefined_Array_Sll
511           | Iir_Predefined_Array_Srl
512           | Iir_Predefined_Array_Sla
513           | Iir_Predefined_Array_Sra =>
514            if Dir_Left then
515               if Cnt < Len then
516                  for I in Cnt .. Len - 1 loop
517                     Res.Val_Array.V (P) := Left.Val_Array.V (I + 1);
518                     P := P + 1;
519                  end loop;
520               else
521                  Cnt := Len;
522               end if;
523               for I in 0 .. Cnt - 1 loop
524                  Res.Val_Array.V (P) := E;
525                  P := P + 1;
526               end loop;
527            else
528               if Cnt > Len then
529                  Cnt := Len;
530               end if;
531               for I in 0 .. Cnt - 1 loop
532                  Res.Val_Array.V (P) := E;
533                  P := P + 1;
534               end loop;
535               for I in Cnt .. Len - 1 loop
536                  Res.Val_Array.V (P) := Left.Val_Array.V (I - Cnt + 1);
537                  P := P + 1;
538               end loop;
539            end if;
540         when Iir_Predefined_Array_Rol
541           | Iir_Predefined_Array_Ror =>
542            for I in 1 .. Len loop
543               Res.Val_Array.V (P) := Left.Val_Array.V (Cnt + 1);
544               P := P + 1;
545               Cnt := Cnt + 1;
546               if Cnt = Len then
547                  Cnt := 0;
548               end if;
549            end loop;
550      end case;
551      return Res;
552   end Execute_Shift_Operator;
553
554   Hex_Chars : constant array (Natural range 0 .. 15) of Character :=
555     "0123456789ABCDEF";
556
557   function Execute_Bit_Vector_To_String (Val : Iir_Value_Literal_Acc;
558                                          Log_Base : Natural)
559                                         return Iir_Value_Literal_Acc
560   is
561      Base : constant Natural := 2 ** Log_Base;
562      Blen : constant Natural := Natural (Val.Bounds.D (1).Length);
563      Str : String (1 .. (Blen + Log_Base - 1) / Log_Base);
564      Pos : Natural;
565      V : Natural;
566      N : Natural;
567   begin
568      V := 0;
569      N := 1;
570      Pos := Str'Last;
571      for I in reverse Val.Val_Array.V'Range loop
572         V := V + Ghdl_B1'Pos (Val.Val_Array.V (I).B1) * N;
573         N := N * 2;
574         if N = Base or else I = Val.Val_Array.V'First then
575            Str (Pos) := Hex_Chars (V);
576            Pos := Pos - 1;
577            N := 1;
578            V := 0;
579         end if;
580      end loop;
581      return String_To_Iir_Value (Str);
582   end Execute_Bit_Vector_To_String;
583
584   procedure Assert_Std_Ulogic_Dc (Loc : Iir)
585   is
586   begin
587      Execute_Failed_Assertion
588        ("assertion",
589         "STD_LOGIC_1164: '-' operand for matching ordering operator",
590         1, Loc);
591   end Assert_Std_Ulogic_Dc;
592
593   procedure Check_Std_Ulogic_Dc (Loc : Iir; V : Grt.Std_Logic_1164.Std_Ulogic)
594   is
595      use Grt.Std_Logic_1164;
596   begin
597      if V = '-' then
598         Assert_Std_Ulogic_Dc (Loc);
599      end if;
600   end Check_Std_Ulogic_Dc;
601
602   --  EXPR is the expression whose implementation is an implicit function.
603   function Execute_Implicit_Function (Block : Block_Instance_Acc;
604                                       Expr: Iir;
605                                       Left_Param : Iir;
606                                       Right_Param : Iir;
607                                       Res_Type : Iir)
608                                      return Iir_Value_Literal_Acc
609   is
610      pragma Unsuppress (Overflow_Check);
611
612      Imp : constant Iir := Strip_Denoting_Name (Get_Implementation (Expr));
613      Func : constant Iir_Predefined_Functions :=
614        Get_Implicit_Definition (Imp);
615
616      --  Rename definition for monadic operations.
617      Left, Right: Iir_Value_Literal_Acc;
618      Operand : Iir_Value_Literal_Acc renames Left;
619      Result: Iir_Value_Literal_Acc;
620
621      procedure Eval_Right is
622      begin
623         Right := Execute_Expression (Block, Right_Param);
624      end Eval_Right;
625
626      --  Eval right argument, check left and right have same length,
627      --  Create RESULT from left.
628      procedure Eval_Array is
629      begin
630         Eval_Right;
631         if Left.Bounds.D (1).Length /= Right.Bounds.D (1).Length then
632            Error_Msg_Constraint (Expr);
633         end if;
634         --  Need to copy as the result is modified.
635         Result := Unshare (Left, Expr_Pool'Access);
636      end Eval_Array;
637   begin
638      --  Eval left operand.
639      case Func is
640         when Iir_Predefined_Now_Function =>
641            Left := null;
642         when Iir_Predefined_Bit_Rising_Edge
643           | Iir_Predefined_Boolean_Rising_Edge
644           | Iir_Predefined_Bit_Falling_Edge
645           | Iir_Predefined_Boolean_Falling_Edge=>
646            Operand := Execute_Name (Block, Left_Param, True);
647         when others =>
648            Left := Execute_Expression (Block, Left_Param);
649      end case;
650      Right := null;
651
652      case Func is
653         when Iir_Predefined_Error =>
654            raise Internal_Error;
655
656         when Iir_Predefined_Array_Array_Concat
657           | Iir_Predefined_Element_Array_Concat
658           | Iir_Predefined_Array_Element_Concat
659           | Iir_Predefined_Element_Element_Concat =>
660            Eval_Right;
661
662            declare
663               --  Type of the index.
664               Idx_Type : constant Iir :=
665                 Get_Nth_Element (Get_Index_Subtype_List (Res_Type), 0);
666
667               -- Array length of the result.
668               Len: Iir_Index32;
669
670               -- Index into the result.
671               Pos: Iir_Index32;
672            begin
673               -- Compute the length of the result.
674               case Func is
675                  when Iir_Predefined_Array_Array_Concat =>
676                     Len := Left.Val_Array.Len + Right.Val_Array.Len;
677                  when Iir_Predefined_Element_Array_Concat =>
678                     Len := 1 + Right.Val_Array.Len;
679                  when Iir_Predefined_Array_Element_Concat =>
680                     Len := Left.Val_Array.Len + 1;
681                  when Iir_Predefined_Element_Element_Concat =>
682                     Len := 1 + 1;
683                  when others =>
684                     raise Program_Error;
685               end case;
686
687               if Func = Iir_Predefined_Array_Array_Concat
688                 and then Left.Val_Array.Len = 0
689               then
690                  if Flags.Vhdl_Std = Vhdl_87 then
691                     --  LRM87 7.2.3
692                     --  [...], unless the left operand is a null array, in
693                     --  which case the result of the concatenation is the
694                     --  right operand.
695                     return Right;
696                  else
697                     --  LRM93 7.2.4
698                     --  If both operands are null arrays, then the result of
699                     --  the concatenation is the right operand.
700                     if Right.Val_Array.Len = 0 then
701                        return Right;
702                     end if;
703                  end if;
704               end if;
705
706               if Flags.Vhdl_Std = Vhdl_87
707                 and then (Func = Iir_Predefined_Array_Array_Concat
708                             or Func = Iir_Predefined_Array_Element_Concat)
709               then
710                  --  LRM87 7.2.3 Adding Operators
711                  --  The left bound if this result is the left bound of the
712                  --  left operand, [...].  The direction of the result is the
713                  --  direction of the left operand, unless the left operand
714                  --  is a null array, in which case the direction of the
715                  --  result is that of the right operand.
716                  Result := Create_Array_Value (Len, 1);
717                  Result.Bounds.D (1) := Create_Range_Value
718                    (Left.Bounds.D (1).Left, null, Left.Bounds.D (1).Dir, Len);
719                  Create_Right_Bound_From_Length (Result.Bounds.D (1), Len);
720               else
721                  --  Create the array result.
722                  Result := Create_Array_Value (Len, 1);
723                  Result.Bounds.D (1) := Create_Bounds_From_Length
724                    (Block, Idx_Type, Len);
725               end if;
726               Check_Range_Constraints
727                 (Block, Result.Bounds.D (1), Idx_Type, Expr);
728
729               -- Fill the result: left.
730               case Func is
731                  when Iir_Predefined_Array_Array_Concat
732                    | Iir_Predefined_Array_Element_Concat =>
733                     for I in Left.Val_Array.V'Range loop
734                        Result.Val_Array.V (I) := Left.Val_Array.V (I);
735                     end loop;
736                     Pos := Left.Val_Array.Len;
737                  when Iir_Predefined_Element_Array_Concat
738                    | Iir_Predefined_Element_Element_Concat =>
739                     Result.Val_Array.V (1) := Left;
740                     Pos := 1;
741                  when others =>
742                     raise Program_Error;
743               end case;
744
745               -- Note: here POS is equal to the position of the last element
746               -- filled, or 0 if no elements were filled.
747
748               --  Fill the result: right.
749               case Func is
750                  when Iir_Predefined_Array_Array_Concat
751                    | Iir_Predefined_Element_Array_Concat =>
752                     for I in Right.Val_Array.V'Range loop
753                        Result.Val_Array.V (Pos + I) := Right.Val_Array.V (I);
754                     end loop;
755                  when Iir_Predefined_Array_Element_Concat
756                    | Iir_Predefined_Element_Element_Concat =>
757                     Result.Val_Array.V (Pos + 1) := Right;
758                  when others =>
759                     raise Program_Error;
760               end case;
761            end;
762
763         when Iir_Predefined_Bit_And
764           | Iir_Predefined_Boolean_And =>
765            if Left.B1 = Lit_Enum_0.B1 then
766               --  Short circuit operator.
767               Result := Lit_Enum_0;
768            else
769               Eval_Right;
770               Result := Boolean_To_Lit (Right.B1 = Lit_Enum_1.B1);
771            end if;
772         when Iir_Predefined_Bit_Nand
773           | Iir_Predefined_Boolean_Nand =>
774            if Left.B1 = Lit_Enum_0.B1 then
775               --  Short circuit operator.
776               Result := Lit_Enum_1;
777            else
778               Eval_Right;
779               Result := Boolean_To_Lit (Right.B1 = Lit_Enum_0.B1);
780            end if;
781         when Iir_Predefined_Bit_Or
782           | Iir_Predefined_Boolean_Or =>
783            if Left.B1 = Lit_Enum_1.B1 then
784               --  Short circuit operator.
785               Result := Lit_Enum_1;
786            else
787               Eval_Right;
788               Result := Boolean_To_Lit (Right.B1 = Lit_Enum_1.B1);
789            end if;
790         when Iir_Predefined_Bit_Nor
791           | Iir_Predefined_Boolean_Nor =>
792            if Left.B1 = Lit_Enum_1.B1 then
793               --  Short circuit operator.
794               Result := Lit_Enum_0;
795            else
796               Eval_Right;
797               Result := Boolean_To_Lit (Right.B1 = Lit_Enum_0.B1);
798            end if;
799         when Iir_Predefined_Bit_Xor
800           | Iir_Predefined_Boolean_Xor =>
801            Eval_Right;
802            Result := Boolean_To_Lit (Left.B1 /= Right.B1);
803         when Iir_Predefined_Bit_Xnor
804           | Iir_Predefined_Boolean_Xnor =>
805            Eval_Right;
806            Result := Boolean_To_Lit (Left.B1 = Right.B1);
807         when Iir_Predefined_Bit_Not
808           | Iir_Predefined_Boolean_Not =>
809            Result := Boolean_To_Lit (Operand.B1 = Lit_Enum_0.B1);
810
811         when Iir_Predefined_Bit_Condition =>
812            Result := Boolean_To_Lit (Operand.B1 = Lit_Enum_1.B1);
813
814         when Iir_Predefined_Array_Sll
815           | Iir_Predefined_Array_Srl
816           | Iir_Predefined_Array_Sla
817           | Iir_Predefined_Array_Sra
818           | Iir_Predefined_Array_Rol
819           | Iir_Predefined_Array_Ror =>
820            Eval_Right;
821            Result := Execute_Shift_Operator (Left, Right.I64, Expr);
822
823         when Iir_Predefined_Enum_Equality
824           | Iir_Predefined_Integer_Equality
825           | Iir_Predefined_Array_Equality
826           | Iir_Predefined_Access_Equality
827           | Iir_Predefined_Physical_Equality
828           | Iir_Predefined_Floating_Equality
829           | Iir_Predefined_Record_Equality
830           | Iir_Predefined_Bit_Match_Equality
831           | Iir_Predefined_Bit_Array_Match_Equality =>
832            Eval_Right;
833            Result := Boolean_To_Lit (Is_Equal (Left, Right));
834         when Iir_Predefined_Enum_Inequality
835           | Iir_Predefined_Integer_Inequality
836           | Iir_Predefined_Array_Inequality
837           | Iir_Predefined_Access_Inequality
838           | Iir_Predefined_Physical_Inequality
839           | Iir_Predefined_Floating_Inequality
840           | Iir_Predefined_Record_Inequality
841           | Iir_Predefined_Bit_Match_Inequality
842           | Iir_Predefined_Bit_Array_Match_Inequality =>
843            Eval_Right;
844            Result := Boolean_To_Lit (not Is_Equal (Left, Right));
845         when Iir_Predefined_Integer_Less
846           | Iir_Predefined_Physical_Less
847           | Iir_Predefined_Enum_Less =>
848            Eval_Right;
849            Result := Boolean_To_Lit (Compare_Value (Left, Right) < Equal);
850         when Iir_Predefined_Integer_Greater
851           | Iir_Predefined_Physical_Greater
852           | Iir_Predefined_Enum_Greater =>
853            Eval_Right;
854            Result := Boolean_To_Lit (Compare_Value (Left, Right) > Equal);
855         when Iir_Predefined_Integer_Less_Equal
856           | Iir_Predefined_Physical_Less_Equal
857           | Iir_Predefined_Enum_Less_Equal =>
858            Eval_Right;
859            Result := Boolean_To_Lit (Compare_Value (Left, Right) <= Equal);
860         when Iir_Predefined_Integer_Greater_Equal
861           | Iir_Predefined_Physical_Greater_Equal
862           | Iir_Predefined_Enum_Greater_Equal =>
863            Eval_Right;
864            Result := Boolean_To_Lit (Compare_Value (Left, Right) >= Equal);
865
866         when Iir_Predefined_Enum_Minimum
867           | Iir_Predefined_Physical_Minimum =>
868            Eval_Right;
869            if Compare_Value (Left, Right) = Less then
870               Result := Left;
871            else
872               Result := Right;
873            end if;
874         when Iir_Predefined_Enum_Maximum
875           | Iir_Predefined_Physical_Maximum =>
876            Eval_Right;
877            if Compare_Value (Left, Right) = Less then
878               Result := Right;
879            else
880               Result := Left;
881            end if;
882
883         when Iir_Predefined_Integer_Plus
884           | Iir_Predefined_Physical_Plus =>
885            Eval_Right;
886            case Left.Kind is
887               when Iir_Value_I64 =>
888                  Result := Create_I64_Value (Left.I64 + Right.I64);
889               when others =>
890                  raise Internal_Error;
891            end case;
892         when Iir_Predefined_Integer_Minus
893           | Iir_Predefined_Physical_Minus =>
894            Eval_Right;
895            case Left.Kind is
896               when Iir_Value_I64 =>
897                  Result := Create_I64_Value (Left.I64 - Right.I64);
898               when others =>
899                  raise Internal_Error;
900            end case;
901         when Iir_Predefined_Integer_Mul =>
902            Eval_Right;
903            case Left.Kind is
904               when Iir_Value_I64 =>
905                  Result := Create_I64_Value (Left.I64 * Right.I64);
906               when others =>
907                  raise Internal_Error;
908            end case;
909         when Iir_Predefined_Integer_Mod =>
910            Eval_Right;
911            case Left.Kind is
912               when Iir_Value_I64 =>
913                  if Right.I64 = 0 then
914                     Error_Msg_Constraint (Expr);
915                  end if;
916                  Result := Create_I64_Value (Left.I64 mod Right.I64);
917               when others =>
918                  raise Internal_Error;
919            end case;
920         when Iir_Predefined_Integer_Rem =>
921            Eval_Right;
922            case Left.Kind is
923               when Iir_Value_I64 =>
924                  if Right.I64 = 0 then
925                     Error_Msg_Constraint (Expr);
926                  end if;
927                  Result := Create_I64_Value (Left.I64 rem Right.I64);
928               when others =>
929                  raise Internal_Error;
930            end case;
931         when Iir_Predefined_Integer_Div =>
932            Eval_Right;
933            case Left.Kind is
934               when Iir_Value_I64 =>
935                  if Right.I64 = 0 then
936                     Error_Msg_Constraint (Expr);
937                  end if;
938                  Result := Create_I64_Value (Left.I64 / Right.I64);
939               when others =>
940                  raise Internal_Error;
941            end case;
942
943         when Iir_Predefined_Integer_Absolute
944           | Iir_Predefined_Physical_Absolute =>
945            case Operand.Kind is
946               when Iir_Value_I64 =>
947                  Result := Create_I64_Value (abs Operand.I64);
948               when others =>
949                  raise Internal_Error;
950            end case;
951
952         when Iir_Predefined_Integer_Negation
953           | Iir_Predefined_Physical_Negation =>
954            case Operand.Kind is
955               when Iir_Value_I64 =>
956                  Result := Create_I64_Value (-Operand.I64);
957               when others =>
958                  raise Internal_Error;
959            end case;
960
961         when Iir_Predefined_Integer_Identity
962           | Iir_Predefined_Physical_Identity =>
963            case Operand.Kind is
964               when Iir_Value_I64 =>
965                  Result := Create_I64_Value (Operand.I64);
966               when others =>
967                  raise Internal_Error;
968            end case;
969
970         when Iir_Predefined_Integer_Exp =>
971            Eval_Right;
972            case Left.Kind is
973               when Iir_Value_I64 =>
974                  if Right.I64 < 0 then
975                     Error_Msg_Constraint (Expr);
976                  end if;
977                  Result := Create_I64_Value (Left.I64 ** Natural (Right.I64));
978               when others =>
979                  raise Internal_Error;
980            end case;
981
982         when Iir_Predefined_Integer_Minimum =>
983            Eval_Right;
984            Result := Create_I64_Value (Ghdl_I64'Min (Left.I64, Right.I64));
985         when Iir_Predefined_Integer_Maximum =>
986            Eval_Right;
987            Result := Create_I64_Value (Ghdl_I64'Max (Left.I64, Right.I64));
988
989         when Iir_Predefined_Floating_Mul =>
990            Eval_Right;
991            Result := Create_F64_Value (Left.F64 * Right.F64);
992         when Iir_Predefined_Floating_Div =>
993            Eval_Right;
994            Result := Create_F64_Value (Left.F64 / Right.F64);
995         when Iir_Predefined_Floating_Minus =>
996            Eval_Right;
997            Result := Create_F64_Value (Left.F64 - Right.F64);
998         when Iir_Predefined_Floating_Plus =>
999            Eval_Right;
1000            Result := Create_F64_Value (Left.F64 + Right.F64);
1001         when Iir_Predefined_Floating_Exp =>
1002            Eval_Right;
1003            Result := Create_F64_Value (Left.F64 ** Integer (Right.I64));
1004         when Iir_Predefined_Floating_Identity =>
1005            Result := Create_F64_Value (Operand.F64);
1006         when Iir_Predefined_Floating_Negation =>
1007            Result := Create_F64_Value (-Operand.F64);
1008         when Iir_Predefined_Floating_Absolute =>
1009            Result := Create_F64_Value (abs (Operand.F64));
1010         when Iir_Predefined_Floating_Less =>
1011            Eval_Right;
1012            Result := Boolean_To_Lit (Left.F64 < Right.F64);
1013         when Iir_Predefined_Floating_Less_Equal =>
1014            Eval_Right;
1015            Result := Boolean_To_Lit (Left.F64 <= Right.F64);
1016         when Iir_Predefined_Floating_Greater =>
1017            Eval_Right;
1018            Result := Boolean_To_Lit (Left.F64 > Right.F64);
1019         when Iir_Predefined_Floating_Greater_Equal =>
1020            Eval_Right;
1021            Result := Boolean_To_Lit (Left.F64 >= Right.F64);
1022
1023         when Iir_Predefined_Floating_Minimum =>
1024            Eval_Right;
1025            Result := Create_F64_Value (Ghdl_F64'Min (Left.F64, Right.F64));
1026         when Iir_Predefined_Floating_Maximum =>
1027            Eval_Right;
1028            Result := Create_F64_Value (Ghdl_F64'Max (Left.F64, Right.F64));
1029
1030         when Iir_Predefined_Integer_Physical_Mul =>
1031            Eval_Right;
1032            Result := Create_I64_Value (Left.I64 * Right.I64);
1033         when Iir_Predefined_Physical_Integer_Mul =>
1034            Eval_Right;
1035            Result := Create_I64_Value (Left.I64 * Right.I64);
1036         when Iir_Predefined_Physical_Physical_Div =>
1037            Eval_Right;
1038            Result := Create_I64_Value (Left.I64 / Right.I64);
1039         when Iir_Predefined_Physical_Integer_Div =>
1040            Eval_Right;
1041            Result := Create_I64_Value (Left.I64 / Right.I64);
1042         when Iir_Predefined_Real_Physical_Mul =>
1043            Eval_Right;
1044            Result := Create_I64_Value
1045              (Ghdl_I64 (Left.F64 * Ghdl_F64 (Right.I64)));
1046         when Iir_Predefined_Physical_Real_Mul =>
1047            Eval_Right;
1048            Result := Create_I64_Value
1049              (Ghdl_I64 (Ghdl_F64 (Left.I64) * Right.F64));
1050         when Iir_Predefined_Physical_Real_Div =>
1051            Eval_Right;
1052            Result := Create_I64_Value
1053              (Ghdl_I64 (Ghdl_F64 (Left.I64) / Right.F64));
1054
1055         when Iir_Predefined_Universal_I_R_Mul =>
1056            Eval_Right;
1057            Result := Create_F64_Value (Ghdl_F64 (Left.I64) * Right.F64);
1058         when Iir_Predefined_Universal_R_I_Mul =>
1059            Eval_Right;
1060            Result := Create_F64_Value (Left.F64 * Ghdl_F64 (Right.I64));
1061
1062         when Iir_Predefined_TF_Array_And =>
1063            Eval_Array;
1064            for I in Result.Val_Array.V'Range loop
1065               Result.Val_Array.V (I).B1 :=
1066                 Result.Val_Array.V (I).B1 and Right.Val_Array.V (I).B1;
1067            end loop;
1068         when Iir_Predefined_TF_Array_Nand =>
1069            Eval_Array;
1070            for I in Result.Val_Array.V'Range loop
1071               Result.Val_Array.V (I).B1 :=
1072                 not (Result.Val_Array.V (I).B1 and Right.Val_Array.V (I).B1);
1073            end loop;
1074         when Iir_Predefined_TF_Array_Or =>
1075            Eval_Array;
1076            for I in Result.Val_Array.V'Range loop
1077               Result.Val_Array.V (I).B1 :=
1078                 Result.Val_Array.V (I).B1 or Right.Val_Array.V (I).B1;
1079            end loop;
1080         when Iir_Predefined_TF_Array_Nor =>
1081            Eval_Array;
1082            for I in Result.Val_Array.V'Range loop
1083               Result.Val_Array.V (I).B1 :=
1084                 not (Result.Val_Array.V (I).B1 or Right.Val_Array.V (I).B1);
1085            end loop;
1086         when Iir_Predefined_TF_Array_Xor =>
1087            Eval_Array;
1088            for I in Result.Val_Array.V'Range loop
1089               Result.Val_Array.V (I).B1 :=
1090                 Result.Val_Array.V (I).B1 xor Right.Val_Array.V (I).B1;
1091            end loop;
1092         when Iir_Predefined_TF_Array_Xnor =>
1093            Eval_Array;
1094            for I in Result.Val_Array.V'Range loop
1095               Result.Val_Array.V (I).B1 :=
1096                 not (Result.Val_Array.V (I).B1 xor Right.Val_Array.V (I).B1);
1097            end loop;
1098
1099         when Iir_Predefined_TF_Array_Element_And =>
1100            Eval_Right;
1101            Result := Unshare (Left, Expr_Pool'Access);
1102            for I in Result.Val_Array.V'Range loop
1103               Result.Val_Array.V (I).B1 :=
1104                 Result.Val_Array.V (I).B1 and Right.B1;
1105            end loop;
1106         when Iir_Predefined_TF_Element_Array_And =>
1107            Eval_Right;
1108            Result := Unshare (Right, Expr_Pool'Access);
1109            for I in Result.Val_Array.V'Range loop
1110               Result.Val_Array.V (I).B1 :=
1111                 Result.Val_Array.V (I).B1 and Left.B1;
1112            end loop;
1113
1114         when Iir_Predefined_TF_Array_Element_Or =>
1115            Eval_Right;
1116            Result := Unshare (Left, Expr_Pool'Access);
1117            for I in Result.Val_Array.V'Range loop
1118               Result.Val_Array.V (I).B1 :=
1119                 Result.Val_Array.V (I).B1 or Right.B1;
1120            end loop;
1121         when Iir_Predefined_TF_Element_Array_Or =>
1122            Eval_Right;
1123            Result := Unshare (Right, Expr_Pool'Access);
1124            for I in Result.Val_Array.V'Range loop
1125               Result.Val_Array.V (I).B1 :=
1126                 Result.Val_Array.V (I).B1 or Left.B1;
1127            end loop;
1128
1129         when Iir_Predefined_TF_Array_Element_Xor =>
1130            Eval_Right;
1131            Result := Unshare (Left, Expr_Pool'Access);
1132            for I in Result.Val_Array.V'Range loop
1133               Result.Val_Array.V (I).B1 :=
1134                 Result.Val_Array.V (I).B1 xor Right.B1;
1135            end loop;
1136         when Iir_Predefined_TF_Element_Array_Xor =>
1137            Eval_Right;
1138            Result := Unshare (Right, Expr_Pool'Access);
1139            for I in Result.Val_Array.V'Range loop
1140               Result.Val_Array.V (I).B1 :=
1141                 Result.Val_Array.V (I).B1 xor Left.B1;
1142            end loop;
1143
1144         when Iir_Predefined_TF_Array_Element_Nand =>
1145            Eval_Right;
1146            Result := Unshare (Left, Expr_Pool'Access);
1147            for I in Result.Val_Array.V'Range loop
1148               Result.Val_Array.V (I).B1 :=
1149                 not (Result.Val_Array.V (I).B1 and Right.B1);
1150            end loop;
1151         when Iir_Predefined_TF_Element_Array_Nand =>
1152            Eval_Right;
1153            Result := Unshare (Right, Expr_Pool'Access);
1154            for I in Result.Val_Array.V'Range loop
1155               Result.Val_Array.V (I).B1 :=
1156                 not (Result.Val_Array.V (I).B1 and Left.B1);
1157            end loop;
1158
1159         when Iir_Predefined_TF_Array_Element_Nor =>
1160            Eval_Right;
1161            Result := Unshare (Left, Expr_Pool'Access);
1162            for I in Result.Val_Array.V'Range loop
1163               Result.Val_Array.V (I).B1 :=
1164                 not (Result.Val_Array.V (I).B1 or Right.B1);
1165            end loop;
1166         when Iir_Predefined_TF_Element_Array_Nor =>
1167            Eval_Right;
1168            Result := Unshare (Right, Expr_Pool'Access);
1169            for I in Result.Val_Array.V'Range loop
1170               Result.Val_Array.V (I).B1 :=
1171                 not (Result.Val_Array.V (I).B1 or Left.B1);
1172            end loop;
1173
1174         when Iir_Predefined_TF_Array_Element_Xnor =>
1175            Eval_Right;
1176            Result := Unshare (Left, Expr_Pool'Access);
1177            for I in Result.Val_Array.V'Range loop
1178               Result.Val_Array.V (I).B1 :=
1179                 not (Result.Val_Array.V (I).B1 xor Right.B1);
1180            end loop;
1181         when Iir_Predefined_TF_Element_Array_Xnor =>
1182            Eval_Right;
1183            Result := Unshare (Right, Expr_Pool'Access);
1184            for I in Result.Val_Array.V'Range loop
1185               Result.Val_Array.V (I).B1 :=
1186                 not (Result.Val_Array.V (I).B1 xor Left.B1);
1187            end loop;
1188
1189         when Iir_Predefined_TF_Array_Not =>
1190            --  Need to copy as the result is modified.
1191            Result := Unshare (Operand, Expr_Pool'Access);
1192            for I in Result.Val_Array.V'Range loop
1193               Result.Val_Array.V (I).B1 := not Result.Val_Array.V (I).B1;
1194            end loop;
1195
1196         when Iir_Predefined_TF_Reduction_And =>
1197            Result := Create_B1_Value (True);
1198            for I in Operand.Val_Array.V'Range loop
1199               Result.B1 := Result.B1 and Operand.Val_Array.V (I).B1;
1200            end loop;
1201         when Iir_Predefined_TF_Reduction_Nand =>
1202            Result := Create_B1_Value (True);
1203            for I in Operand.Val_Array.V'Range loop
1204               Result.B1 := Result.B1 and Operand.Val_Array.V (I).B1;
1205            end loop;
1206            Result.B1 := not Result.B1;
1207         when Iir_Predefined_TF_Reduction_Or =>
1208            Result := Create_B1_Value (False);
1209            for I in Operand.Val_Array.V'Range loop
1210               Result.B1 := Result.B1 or Operand.Val_Array.V (I).B1;
1211            end loop;
1212         when Iir_Predefined_TF_Reduction_Nor =>
1213            Result := Create_B1_Value (False);
1214            for I in Operand.Val_Array.V'Range loop
1215               Result.B1 := Result.B1 or Operand.Val_Array.V (I).B1;
1216            end loop;
1217            Result.B1 := not Result.B1;
1218         when Iir_Predefined_TF_Reduction_Xor =>
1219            Result := Create_B1_Value (False);
1220            for I in Operand.Val_Array.V'Range loop
1221               Result.B1 := Result.B1 xor Operand.Val_Array.V (I).B1;
1222            end loop;
1223         when Iir_Predefined_TF_Reduction_Xnor =>
1224            Result := Create_B1_Value (False);
1225            for I in Operand.Val_Array.V'Range loop
1226               Result.B1 := Result.B1 xor Operand.Val_Array.V (I).B1;
1227            end loop;
1228            Result.B1 := not Result.B1;
1229
1230         when Iir_Predefined_Bit_Rising_Edge
1231           | Iir_Predefined_Boolean_Rising_Edge =>
1232            return Boolean_To_Lit
1233              (Execute_Event_Attribute (Operand)
1234                 and then Execute_Signal_Value (Operand).B1 = True);
1235         when Iir_Predefined_Bit_Falling_Edge
1236           | Iir_Predefined_Boolean_Falling_Edge =>
1237            return Boolean_To_Lit
1238              (Execute_Event_Attribute (Operand)
1239                 and then Execute_Signal_Value (Operand).B1 = False);
1240
1241         when Iir_Predefined_Array_Greater =>
1242            Eval_Right;
1243            Result := Boolean_To_Lit (Compare_Value (Left, Right) = Greater);
1244
1245         when Iir_Predefined_Array_Greater_Equal =>
1246            Eval_Right;
1247            Result := Boolean_To_Lit (Compare_Value (Left, Right) >= Equal);
1248
1249         when Iir_Predefined_Array_Less =>
1250            Eval_Right;
1251            Result := Boolean_To_Lit (Compare_Value (Left, Right) = Less);
1252
1253         when Iir_Predefined_Array_Less_Equal =>
1254            Eval_Right;
1255            Result := Boolean_To_Lit (Compare_Value (Left, Right) <= Equal);
1256
1257         when Iir_Predefined_Array_Minimum =>
1258            Eval_Right;
1259            if Compare_Value (Left, Right) = Less then
1260               Result := Left;
1261            else
1262               Result := Right;
1263            end if;
1264         when Iir_Predefined_Array_Maximum =>
1265            Eval_Right;
1266            if Compare_Value (Left, Right) = Less then
1267               Result := Right;
1268            else
1269               Result := Left;
1270            end if;
1271
1272         when Iir_Predefined_Vector_Maximum =>
1273            declare
1274               El_St : constant Iir :=
1275                 Get_Return_Type (Get_Implementation (Expr));
1276               V : Iir_Value_Literal_Acc;
1277            begin
1278               Result := Execute_Low_Limit (Execute_Bounds (Block, El_St));
1279               for I in Left.Val_Array.V'Range loop
1280                  V := Left.Val_Array.V (I);
1281                  if Compare_Value (V, Result) = Greater then
1282                     Result := V;
1283                  end if;
1284               end loop;
1285            end;
1286         when Iir_Predefined_Vector_Minimum =>
1287            declare
1288               El_St : constant Iir :=
1289                 Get_Return_Type (Get_Implementation (Expr));
1290               V : Iir_Value_Literal_Acc;
1291            begin
1292               Result := Execute_High_Limit (Execute_Bounds (Block, El_St));
1293               for I in Left.Val_Array.V'Range loop
1294                  V := Left.Val_Array.V (I);
1295                  if Compare_Value (V, Result) = Less then
1296                     Result := V;
1297                  end if;
1298               end loop;
1299            end;
1300
1301         when Iir_Predefined_Endfile =>
1302            Result := Boolean_To_Lit (File_Operation.Endfile (Left, Null_Iir));
1303
1304         when Iir_Predefined_Now_Function =>
1305            Result := Create_I64_Value (Ghdl_I64 (Grt.Types.Current_Time));
1306
1307         when Iir_Predefined_Integer_To_String
1308           | Iir_Predefined_Floating_To_String
1309           | Iir_Predefined_Physical_To_String =>
1310            Result := String_To_Iir_Value
1311              (Execute_Image_Attribute (Left, Get_Type (Left_Param)));
1312
1313         when Iir_Predefined_Enum_To_String =>
1314            declare
1315               use Name_Table;
1316               Base_Type : constant Iir :=
1317                 Get_Base_Type (Get_Type (Left_Param));
1318               Lits : constant Iir_Flist :=
1319                 Get_Enumeration_Literal_List (Base_Type);
1320               Pos : constant Natural := Get_Enum_Pos (Left);
1321               Id : Name_Id;
1322            begin
1323               if Base_Type = Vhdl.Std_Package.Character_Type_Definition then
1324                  Result := String_To_Iir_Value ((1 => Character'Val (Pos)));
1325               else
1326                  Id := Get_Identifier (Get_Nth_Element (Lits, Pos));
1327                  if Is_Character (Id) then
1328                     Result := String_To_Iir_Value ((1 => Get_Character (Id)));
1329                  else
1330                     declare
1331                        Img : String := Image (Id);
1332                     begin
1333                        if Img (Img'First) = '\' then
1334                           --  Reformat extended identifiers for to_image.
1335                           pragma Assert (Img (Img'Last) = '\');
1336                           declare
1337                              Npos : Natural;
1338                              K : Natural;
1339                              C : Character;
1340                           begin
1341                              Npos := Img'First;
1342                              K := Npos + 1;
1343                              while K < Img'Last loop
1344                                 C := Img (K);
1345                                 Img (Npos) := C;
1346                                 Npos := Npos + 1;
1347                                 if C = '\' then
1348                                    K := K + 2;
1349                                 else
1350                                    K := K + 1;
1351                                 end if;
1352                              end loop;
1353                              Result := String_To_Iir_Value
1354                                (Img (Img'First .. Npos - 1));
1355                           end;
1356                        else
1357                           Result := String_To_Iir_Value (Img);
1358                        end if;
1359                     end;
1360                  end if;
1361               end if;
1362            end;
1363
1364         when Iir_Predefined_Array_Char_To_String =>
1365            declare
1366               Lits : constant Iir_Flist :=
1367                 Get_Enumeration_Literal_List
1368                 (Get_Base_Type
1369                    (Get_Element_Subtype (Get_Type (Left_Param))));
1370               Str : String (1 .. Natural (Left.Bounds.D (1).Length));
1371               Pos : Natural;
1372            begin
1373               for I in Left.Val_Array.V'Range loop
1374                  Pos := Get_Enum_Pos (Left.Val_Array.V (I));
1375                  Str (Positive (I)) := Name_Table.Get_Character
1376                    (Get_Identifier (Get_Nth_Element (Lits, Pos)));
1377               end loop;
1378               Result := String_To_Iir_Value (Str);
1379            end;
1380
1381         when Iir_Predefined_Bit_Vector_To_Hstring =>
1382            return Execute_Bit_Vector_To_String (Left, 4);
1383
1384         when Iir_Predefined_Bit_Vector_To_Ostring =>
1385            return Execute_Bit_Vector_To_String (Left, 3);
1386
1387         when Iir_Predefined_Real_To_String_Digits =>
1388            Eval_Right;
1389            declare
1390               Str : Grt.To_Strings.String_Real_Format;
1391               Last : Natural;
1392            begin
1393               Grt.To_Strings.To_String
1394                 (Str, Last, Left.F64, Ghdl_I32 (Right.I64));
1395               Result := String_To_Iir_Value (Str (1 .. Last));
1396            end;
1397         when Iir_Predefined_Real_To_String_Format =>
1398            Eval_Right;
1399            declare
1400               Format : String (1 .. Natural (Right.Val_Array.Len) + 1);
1401               Str : Grt.To_Strings.String_Real_Format;
1402               Last : Natural;
1403            begin
1404               for I in Right.Val_Array.V'Range loop
1405                  Format (Positive (I)) :=
1406                    Character'Val (Right.Val_Array.V (I).E8);
1407               end loop;
1408               Format (Format'Last) := ASCII.NUL;
1409               Grt.To_Strings.To_String
1410                 (Str, Last, Left.F64, To_Ghdl_C_String (Format'Address));
1411               Result := String_To_Iir_Value (Str (1 .. Last));
1412            end;
1413         when Iir_Predefined_Time_To_String_Unit =>
1414            Eval_Right;
1415            declare
1416               Str : Grt.To_Strings.String_Time_Unit;
1417               First : Natural;
1418               Unit : Iir;
1419            begin
1420               Unit := Get_Unit_Chain (Vhdl.Std_Package.Time_Type_Definition);
1421               while Unit /= Null_Iir loop
1422                  exit when Vhdl.Evaluation.Get_Physical_Value (Unit)
1423                    = Int64 (Right.I64);
1424                  Unit := Get_Chain (Unit);
1425               end loop;
1426               if Unit = Null_Iir then
1427                  Error_Msg_Exec
1428                    ("to_string for time called with wrong unit", Expr);
1429               end if;
1430               Grt.To_Strings.To_String (Str, First, Left.I64, Right.I64);
1431               Result := String_To_Iir_Value
1432                 (Str (First .. Str'Last) & ' '
1433                    & Name_Table.Image (Get_Identifier (Unit)));
1434            end;
1435
1436         when Iir_Predefined_Std_Ulogic_Match_Equality =>
1437            Eval_Right;
1438            declare
1439               use Grt.Std_Logic_1164;
1440            begin
1441               Result := Create_E8_Value
1442                 (Std_Ulogic'Pos
1443                    (Match_Eq_Table (Std_Ulogic'Val (Left.E8),
1444                                     Std_Ulogic'Val (Right.E8))));
1445            end;
1446         when Iir_Predefined_Std_Ulogic_Match_Inequality =>
1447            Eval_Right;
1448            declare
1449               use Grt.Std_Logic_1164;
1450            begin
1451               Result := Create_E8_Value
1452                 (Std_Ulogic'Pos
1453                    (Not_Table (Match_Eq_Table (Std_Ulogic'Val (Left.E8),
1454                                                Std_Ulogic'Val (Right.E8)))));
1455            end;
1456         when Iir_Predefined_Std_Ulogic_Match_Ordering_Functions =>
1457            Eval_Right;
1458            declare
1459               use Grt.Std_Logic_1164;
1460               L : constant Std_Ulogic := Std_Ulogic'Val (Left.E8);
1461               R : constant Std_Ulogic := Std_Ulogic'Val (Right.E8);
1462               Res : Std_Ulogic;
1463            begin
1464               Check_Std_Ulogic_Dc (Expr, L);
1465               Check_Std_Ulogic_Dc (Expr, R);
1466               case Iir_Predefined_Std_Ulogic_Match_Ordering_Functions (Func)
1467                  is
1468                  when Iir_Predefined_Std_Ulogic_Match_Less =>
1469                     Res := Match_Lt_Table (L, R);
1470                  when Iir_Predefined_Std_Ulogic_Match_Less_Equal =>
1471                     Res := Or_Table (Match_Lt_Table (L, R),
1472                                      Match_Eq_Table (L, R));
1473                  when Iir_Predefined_Std_Ulogic_Match_Greater =>
1474                     Res := Not_Table (Or_Table (Match_Lt_Table (L, R),
1475                                                 Match_Eq_Table (L, R)));
1476                  when Iir_Predefined_Std_Ulogic_Match_Greater_Equal =>
1477                     Res := Not_Table (Match_Lt_Table (L, R));
1478               end case;
1479               Result := Create_E8_Value (Std_Ulogic'Pos (Res));
1480            end;
1481
1482         when Iir_Predefined_Std_Ulogic_Array_Match_Equality
1483           | Iir_Predefined_Std_Ulogic_Array_Match_Inequality =>
1484            Eval_Right;
1485            if Left.Bounds.D (1).Length /= Right.Bounds.D (1).Length then
1486               Error_Msg_Constraint (Expr);
1487            end if;
1488            declare
1489               use Grt.Std_Logic_1164;
1490               Res : Std_Ulogic := '1';
1491               Le, Re : Std_Ulogic;
1492               Has_Match_Err : Boolean;
1493            begin
1494               Has_Match_Err := False;
1495               for I in Left.Val_Array.V'Range loop
1496                  Le := Std_Ulogic'Val (Left.Val_Array.V (I).E8);
1497                  Re := Std_Ulogic'Val (Right.Val_Array.V (I).E8);
1498                  if (Le = '-' or Re = '-') and then not Has_Match_Err then
1499                     Assert_Std_Ulogic_Dc (Expr);
1500                     Has_Match_Err := True;
1501                  end if;
1502                  Res := And_Table (Res, Match_Eq_Table (Le, Re));
1503               end loop;
1504               if Func = Iir_Predefined_Std_Ulogic_Array_Match_Inequality then
1505                  Res := Not_Table (Res);
1506               end if;
1507               Result := Create_E8_Value (Std_Ulogic'Pos (Res));
1508            end;
1509
1510         when others =>
1511            Error_Msg_Elab (Expr, "execute_implicit_function: unimplemented " &
1512                              Iir_Predefined_Functions'Image (Func));
1513            raise Internal_Error;
1514      end case;
1515      return Result;
1516   exception
1517      when Constraint_Error =>
1518         Error_Msg_Constraint (Expr);
1519   end Execute_Implicit_Function;
1520
1521   procedure Execute_Implicit_Procedure
1522     (Block: Block_Instance_Acc; Stmt: Iir_Procedure_Call)
1523   is
1524      Imp : constant Iir := Get_Implementation (Stmt);
1525      Assoc_Chain : constant Iir := Get_Parameter_Association_Chain (Stmt);
1526      Inter_Chain : constant Iir := Get_Interface_Declaration_Chain (Imp);
1527      Assoc: Iir;
1528      Formal : Iir;
1529      Val : Iir;
1530      Args: Iir_Value_Literal_Array (0 .. 3);
1531      Expr_Mark : Mark_Type;
1532   begin
1533      Mark (Expr_Mark, Expr_Pool);
1534      Assoc := Assoc_Chain;
1535      Formal := Inter_Chain;
1536      for I in Iir_Index32 loop
1537         exit when Assoc = Null_Iir;
1538         case Get_Kind (Assoc) is
1539            when Iir_Kind_Association_Element_By_Expression =>
1540               Val := Get_Actual (Assoc);
1541            when Iir_Kind_Association_Element_Open =>
1542               Val := Get_Default_Value (Formal);
1543            when others =>
1544               raise Internal_Error;
1545         end case;
1546         Args (I) := Execute_Expression (Block, Val);
1547         Assoc := Get_Chain (Assoc);
1548         Formal := Get_Chain (Formal);
1549      end loop;
1550      case Get_Implicit_Definition (Imp) is
1551         when Iir_Predefined_Deallocate =>
1552            if Args (0).Val_Access /= null then
1553               Free_Heap_Value (Args (0));
1554               Args (0).Val_Access := null;
1555            end if;
1556         when Iir_Predefined_File_Open =>
1557            File_Operation.File_Open
1558              (Args (0), Args (1), Args (2), Inter_Chain, Stmt);
1559         when Iir_Predefined_File_Open_Status =>
1560            File_Operation.File_Open_Status
1561              (Args (0), Args (1), Args (2), Args (3),
1562               Get_Chain (Inter_Chain), Stmt);
1563         when Iir_Predefined_Write =>
1564            if Get_Text_File_Flag (Get_Type (Inter_Chain)) then
1565               File_Operation.Write_Text (Args (0), Args (1));
1566            else
1567               File_Operation.Write_Binary (Args (0), Args (1));
1568            end if;
1569         when Iir_Predefined_Read_Length =>
1570            if Get_Text_File_Flag (Get_Type (Inter_Chain)) then
1571               File_Operation.Read_Length_Text
1572                 (Args (0), Args (1), Args (2));
1573            else
1574               File_Operation.Read_Length_Binary
1575                 (Args (0), Args (1), Args (2));
1576            end if;
1577         when Iir_Predefined_Read =>
1578            File_Operation.Read_Binary (Args (0), Args (1));
1579         when Iir_Predefined_Flush =>
1580            File_Operation.Flush (Args (0));
1581         when Iir_Predefined_File_Close =>
1582            if Get_Text_File_Flag (Get_Type (Inter_Chain)) then
1583               File_Operation.File_Close_Text (Args (0), Stmt);
1584            else
1585               File_Operation.File_Close_Binary (Args (0), Stmt);
1586            end if;
1587         when others =>
1588            Error_Kind ("execute_implicit_procedure",
1589                        Get_Implicit_Definition (Imp));
1590      end case;
1591      Release (Expr_Mark, Expr_Pool);
1592   end Execute_Implicit_Procedure;
1593
1594   procedure Execute_Foreign_Procedure
1595     (Block: Block_Instance_Acc; Stmt: Iir_Procedure_Call)
1596   is
1597      Imp : constant Iir := Get_Implementation (Stmt);
1598      Assoc_Chain : constant Iir := Get_Parameter_Association_Chain (Stmt);
1599      Assoc: Iir;
1600      Args: Iir_Value_Literal_Array (0 .. 3) := (others => null);
1601      Expr_Mark : Mark_Type;
1602   begin
1603      Mark (Expr_Mark, Expr_Pool);
1604      Assoc := Assoc_Chain;
1605      for I in Args'Range loop
1606         exit when Assoc = Null_Iir;
1607         Args (I) := Execute_Expression (Block, Get_Actual (Assoc));
1608         Assoc := Get_Chain (Assoc);
1609      end loop;
1610      case Get_Identifier (Imp) is
1611         when Std_Names.Name_Untruncated_Text_Read =>
1612            File_Operation.Untruncated_Text_Read
1613              (Args (0), Args (1), Args (2));
1614         when Std_Names.Name_Control_Simulation =>
1615            --  FIXME: handle stop properly.
1616            --  FIXME: this is the only place where longjump is called.
1617            Grt.Lib.Ghdl_Control_Simulation
1618              (Args (0).B1, Args (1).B1, Std_Integer (Args (2).I64));
1619            --  Do not return.
1620         when Std_Names.Name_Textio_Write_Real =>
1621            File_Operation.Textio_Write_Real
1622              (Args (0), Args (1), Args (2).F64, Std_Integer (Args (3).I64));
1623         when others =>
1624            Error_Msg_Exec ("unsupported foreign procedure call", Stmt);
1625      end case;
1626      Release (Expr_Mark, Expr_Pool);
1627   end Execute_Foreign_Procedure;
1628
1629   -- Compute the offset for INDEX into a range BOUNDS.
1630   -- EXPR is only used in case of error.
1631   function Get_Index_Offset
1632     (Index: Iir_Value_Literal_Acc;
1633      Bounds: Iir_Value_Literal_Acc;
1634      Expr: Iir)
1635      return Iir_Index32
1636   is
1637      Left_Pos, Right_Pos: Iir_Value_Literal_Acc;
1638   begin
1639      Left_Pos := Bounds.Left;
1640      Right_Pos := Bounds.Right;
1641      if Index.Kind /= Left_Pos.Kind or else Index.Kind /= Right_Pos.Kind then
1642         raise Internal_Error;
1643      end if;
1644      case Iir_Value_Discrete (Index.Kind) is
1645         when Iir_Value_B1 =>
1646            case Bounds.Dir is
1647               when Dir_To =>
1648                  if Index.B1 >= Left_Pos.B1 and then
1649                    Index.B1 <= Right_Pos.B1
1650                  then
1651                     -- to
1652                     return Ghdl_B1'Pos (Index.B1) - Ghdl_B1'Pos (Left_Pos.B1);
1653                  end if;
1654               when Dir_Downto =>
1655                  if Index.B1 <= Left_Pos.B1 and then
1656                    Index.B1 >= Right_Pos.B1
1657                  then
1658                     -- downto
1659                     return Ghdl_B1'Pos (Left_Pos.B1) - Ghdl_B1'Pos (Index.B1);
1660                  end if;
1661            end case;
1662         when Iir_Value_E8 =>
1663            case Bounds.Dir is
1664               when Dir_To =>
1665                  if Index.E8 >= Left_Pos.E8 and then
1666                    Index.E8 <= Right_Pos.E8
1667                  then
1668                     -- to
1669                     return Iir_Index32 (Index.E8 - Left_Pos.E8);
1670                  end if;
1671               when Dir_Downto =>
1672                  if Index.E8 <= Left_Pos.E8 and then
1673                    Index.E8 >= Right_Pos.E8
1674                  then
1675                     -- downto
1676                     return Iir_Index32 (Left_Pos.E8 - Index.E8);
1677                  end if;
1678            end case;
1679         when Iir_Value_E32 =>
1680            case Bounds.Dir is
1681               when Dir_To =>
1682                  if Index.E32 >= Left_Pos.E32 and then
1683                    Index.E32 <= Right_Pos.E32
1684                  then
1685                     -- to
1686                     return Iir_Index32 (Index.E32 - Left_Pos.E32);
1687                  end if;
1688               when Dir_Downto =>
1689                  if Index.E32 <= Left_Pos.E32 and then
1690                    Index.E32 >= Right_Pos.E32
1691                  then
1692                     -- downto
1693                     return Iir_Index32 (Left_Pos.E32 - Index.E32);
1694                  end if;
1695            end case;
1696         when Iir_Value_I64 =>
1697            case Bounds.Dir is
1698               when Dir_To =>
1699                  if Index.I64 >= Left_Pos.I64 and then
1700                    Index.I64 <= Right_Pos.I64
1701                  then
1702                     -- to
1703                     return Iir_Index32 (Index.I64 - Left_Pos.I64);
1704                  end if;
1705               when Dir_Downto =>
1706                  if Index.I64 <= Left_Pos.I64 and then
1707                    Index.I64 >= Right_Pos.I64
1708                  then
1709                     -- downto
1710                     return Iir_Index32 (Left_Pos.I64 - Index.I64);
1711                  end if;
1712            end case;
1713      end case;
1714      Error_Msg_Constraint (Expr);
1715      return 0;
1716   end Get_Index_Offset;
1717
1718   --  Create an iir_value_literal of kind iir_value_array and of life LIFE.
1719   --  Allocate the array of bounds, and fill it from A_TYPE.
1720   --  Allocate the array of values.
1721   function Create_Array_Bounds_From_Type (Block : Block_Instance_Acc;
1722                                           A_Type : Iir;
1723                                           Create_Val_Array : Boolean)
1724                                          return Iir_Value_Literal_Acc
1725   is
1726      --  Only for constrained subtypes.
1727      pragma Assert (Get_Constraint_State (A_Type) = Fully_Constrained);
1728
1729      Index_List : constant Iir_Flist := Get_Index_Subtype_List (A_Type);
1730      Res : Iir_Value_Literal_Acc;
1731      Len : Iir_Index32;
1732      Bound : Iir_Value_Literal_Acc;
1733   begin
1734      Res := Create_Array_Value (Iir_Index32 (Get_Nbr_Elements (Index_List)));
1735      Len := 1;
1736      for I in 1 .. Res.Bounds.Nbr_Dims loop
1737         Bound := Execute_Bounds
1738           (Block, Get_Nth_Element (Index_List, Natural (I - 1)));
1739         Len := Len * Bound.Length;
1740         Res.Bounds.D (I) := Bound;
1741      end loop;
1742      if Create_Val_Array then
1743         Create_Array_Data (Res, Len);
1744      end if;
1745      return Res;
1746   end Create_Array_Bounds_From_Type;
1747
1748   --  Return the steps (ie, offset in the array when index DIM is increased
1749   --  by one) for array ARR and dimension DIM.
1750   function Get_Step_For_Dim (Arr: Iir_Value_Literal_Acc; Dim : Natural)
1751     return Iir_Index32
1752   is
1753      Bounds : Value_Bounds_Array_Acc renames Arr.Bounds;
1754      Res : Iir_Index32;
1755   begin
1756      Res := 1;
1757      for I in Iir_Index32 (Dim + 1) .. Bounds.Nbr_Dims loop
1758         Res := Res * Bounds.D (I).Length;
1759      end loop;
1760      return Res;
1761   end Get_Step_For_Dim;
1762
1763   --  Create a literal for a string or a bit_string
1764   function String_To_Enumeration_Array_1 (Str: Iir; El_Type : Iir)
1765                                          return Iir_Value_Literal_Acc
1766   is
1767      pragma Assert (Get_Kind (Str) = Iir_Kind_String_Literal8);
1768      Id : constant String8_Id := Get_String8_Id (Str);
1769      Len : constant Iir_Index32 := Iir_Index32 (Get_String_Length (Str));
1770
1771      El_Btype : constant Iir := Get_Base_Type (El_Type);
1772
1773      Lit: Iir_Value_Literal_Acc;
1774      El : Iir_Value_Literal_Acc;
1775
1776      Pos : Nat8;
1777   begin
1778      Lit := Create_Array_Value (Len, 1);
1779
1780      for I in Lit.Val_Array.V'Range loop
1781         -- FIXME: use literal from type ??
1782         Pos := Str_Table.Element_String8 (Id, Pos32 (I));
1783         El := Create_Enum_Value (Natural (Pos), El_Btype);
1784         Lit.Val_Array.V (I) := El;
1785      end loop;
1786
1787      return Lit;
1788   end String_To_Enumeration_Array_1;
1789
1790   --  Create a literal for a string or a bit_string
1791   function Execute_String_Literal (Str: Iir; Block_Type : Block_Instance_Acc)
1792                                   return Iir_Value_Literal_Acc
1793   is
1794      Array_Type: constant Iir := Get_Type (Str);
1795      Index_Types : constant Iir_Flist := Get_Index_Subtype_List (Array_Type);
1796      Res : Iir_Value_Literal_Acc;
1797   begin
1798      --  Array must be unidimensional.
1799      pragma Assert (Get_Nbr_Elements (Index_Types) = 1);
1800
1801      Res := String_To_Enumeration_Array_1
1802        (Str, Get_Element_Subtype (Array_Type));
1803
1804      --  When created from static evaluation, a string may still have an
1805      --  unconstrained type.
1806      if Get_Constraint_State (Array_Type) /= Fully_Constrained then
1807         Res.Bounds.D (1) :=
1808           Create_Range_Value (Create_I64_Value (1),
1809                               Create_I64_Value (Ghdl_I64 (Res.Val_Array.Len)),
1810                               Dir_To,
1811                               Res.Val_Array.Len);
1812      else
1813         Res.Bounds.D (1) :=
1814           Execute_Bounds (Block_Type, Get_Nth_Element (Index_Types, 0));
1815      end if;
1816
1817      --  The range may not be statically constant.
1818      if Res.Bounds.D (1).Length /= Res.Val_Array.Len then
1819         Error_Msg_Constraint (Str);
1820      end if;
1821
1822      return Res;
1823   end Execute_String_Literal;
1824
1825   --  Fill LENGTH elements of RES, starting at ORIG by steps of STEP.
1826   --  Use expressions from (BLOCK, AGGREGATE) to fill the elements.
1827   --  EL_TYPE is the type of the array element.
1828   procedure Fill_Array_Aggregate_1 (Block : Block_Instance_Acc;
1829                                     Aggregate : Iir;
1830                                     Res : Iir_Value_Literal_Acc;
1831                                     Orig : Iir_Index32;
1832                                     Step : Iir_Index32;
1833                                     Dim : Iir_Index32;
1834                                     Nbr_Dim : Iir_Index32;
1835                                     El_Type : Iir)
1836   is
1837      Value : Iir;
1838      Bound : constant Iir_Value_Literal_Acc := Res.Bounds.D (Dim);
1839      Length : constant Iir_Index32 := Bound.Length;
1840
1841      procedure Set_Elem (Pos : Iir_Index32)
1842      is
1843         Val : Iir_Value_Literal_Acc;
1844      begin
1845         if Dim = Nbr_Dim then
1846            --  VALUE is an expression (which may be an aggregate, but not
1847            --  a sub-aggregate.
1848            Val := Execute_Expression_With_Type (Block, Value, El_Type);
1849            --  LRM93 7.3.2.2
1850            --  For a multi-dimensional aggregate of dimension n, a check
1851            --  is made that all (n-1)-dimensional subaggregates have the
1852            --  same bounds.
1853            --  GHDL: I have added an implicit array conversion, however
1854            --   it may be useful to allow cases like this:
1855            --     type str_array is array (natural range <>)
1856            --        of string (10 downto 1);
1857            --     constant floats : str_array :=
1858            --         ( "00000000.0", HT & "+1.5ABCDE");
1859            --   The subtype of the first sub-aggregate (0.0) is
1860            --   determinated by the context, according to rule 9 and 4
1861            --   of LRM93 7.3.2.2 and therefore is string (10 downto 1),
1862            --   while the subtype of the second sub-aggregate (HT & ...)
1863            --   is determinated by rules 1 and 2 of LRM 7.2.4, and is
1864            --   string (1 to 10).
1865            --   Unless an implicit conversion is used, according to the
1866            --   LRM, this should fail, but it makes no sens.
1867            --
1868            --   FIXME: Add a warning, a flag ?
1869            --Implicit_Array_Conversion (Block, Val, El_Type, Value);
1870            --Check_Constraints (Block, Val, El_Type, Value);
1871            Res.Val_Array.V (1 + Orig + Pos * Step) := Val;
1872         else
1873            case Get_Kind (Value) is
1874               when Iir_Kind_Aggregate =>
1875                  --  VALUE is a sub-aggregate.
1876                  Fill_Array_Aggregate_1 (Block, Value, Res,
1877                                          Orig + Pos * Step,
1878                                          Step / Res.Bounds.D (Dim + 1).Length,
1879                                          Dim + 1, Nbr_Dim, El_Type);
1880               when Iir_Kind_String_Literal8 =>
1881                  pragma Assert (Dim + 1 = Nbr_Dim);
1882                  Val := String_To_Enumeration_Array_1 (Value, El_Type);
1883                  if Val.Val_Array.Len /= Res.Bounds.D (Nbr_Dim).Length then
1884                     Error_Msg_Constraint (Value);
1885                  end if;
1886                  for I in Val.Val_Array.V'Range loop
1887                     Res.Val_Array.V (Orig + Pos * Step + I) :=
1888                       Val.Val_Array.V (I);
1889                  end loop;
1890               when others =>
1891                  Error_Kind ("fill_array_aggregate_1", Value);
1892            end case;
1893         end if;
1894      end Set_Elem;
1895
1896      procedure Set_Elem_By_Expr (Expr : Iir)
1897      is
1898         Expr_Pos: Iir_Value_Literal_Acc;
1899      begin
1900         Expr_Pos := Execute_Expression (Block, Expr);
1901         Set_Elem (Get_Index_Offset (Expr_Pos, Bound, Expr));
1902      end Set_Elem_By_Expr;
1903
1904      procedure Set_Elem_By_Range (Expr : Iir)
1905      is
1906         A_Range : Iir_Value_Literal_Acc;
1907         High, Low : Iir_Value_Literal_Acc;
1908      begin
1909         A_Range := Execute_Bounds (Block, Expr);
1910         if Is_Null_Range (A_Range) then
1911            return;
1912         end if;
1913         if A_Range.Dir = Dir_To then
1914            High := A_Range.Right;
1915            Low := A_Range.Left;
1916         else
1917            High := A_Range.Left;
1918            Low := A_Range.Right;
1919         end if;
1920
1921         --  Locally modified (incremented)
1922         Low := Unshare (Low, Expr_Pool'Access);
1923
1924         loop
1925            Set_Elem (Get_Index_Offset (Low, Bound, Expr));
1926            exit when Is_Equal (Low, High);
1927            Increment (Low);
1928         end loop;
1929      end Set_Elem_By_Range;
1930
1931      Assoc : Iir;
1932      Pos : Iir_Index32;
1933   begin
1934      Assoc := Get_Association_Choices_Chain (Aggregate);
1935      Pos := 0;
1936      while Assoc /= Null_Iir loop
1937         Value := Get_Associated_Expr (Assoc);
1938         loop
1939            case Get_Kind (Assoc) is
1940               when Iir_Kind_Choice_By_None =>
1941                  if Get_Element_Type_Flag (Assoc) then
1942                     if Pos >= Length then
1943                        Error_Msg_Constraint (Assoc);
1944                     end if;
1945
1946                     Set_Elem (Pos);
1947                     Pos := Pos + 1;
1948                  else
1949                     declare
1950                        Val : Iir_Value_Literal_Acc;
1951                     begin
1952                        Val := Execute_Expression (Block, Value);
1953                        pragma Assert (Val.Kind = Iir_Value_Array);
1954                        pragma Assert (Val.Bounds.Nbr_Dims = 1);
1955                        for I in 1 .. Val.Val_Array.Len loop
1956                           if Pos >= Length then
1957                              Error_Msg_Constraint (Assoc);
1958                           end if;
1959                           Res.Val_Array.V (1 + Orig + Pos * Step) :=
1960                             Val.Val_Array.V (I);
1961                           Pos := Pos + 1;
1962                        end loop;
1963                     end;
1964                  end if;
1965               when Iir_Kind_Choice_By_Expression =>
1966                  Set_Elem_By_Expr (Get_Choice_Expression (Assoc));
1967               when Iir_Kind_Choice_By_Range =>
1968                  Set_Elem_By_Range (Get_Choice_Range (Assoc));
1969               when Iir_Kind_Choice_By_Others =>
1970                  for J in 1 .. Length loop
1971                     if Res.Val_Array.V (Orig + J * Step) = null then
1972                        Set_Elem (J - 1);
1973                     end if;
1974                  end loop;
1975                  return;
1976               when others =>
1977                  raise Internal_Error;
1978            end case;
1979            Assoc := Get_Chain (Assoc);
1980            exit when Assoc = Null_Iir;
1981            exit when not Get_Same_Alternative_Flag (Assoc);
1982         end loop;
1983      end loop;
1984
1985      --  Check each elements have been set.
1986      --  FIXME: check directly with type.
1987      for J in 1 .. Length loop
1988         if Res.Val_Array.V (Orig + J * Step) = null then
1989            Error_Msg_Constraint (Aggregate);
1990         end if;
1991      end loop;
1992   end Fill_Array_Aggregate_1;
1993
1994   --  Use expressions from (BLOCK, AGGREGATE) to fill RES.
1995   procedure Fill_Array_Aggregate (Block : Block_Instance_Acc;
1996                                   Aggregate : Iir;
1997                                   Res : Iir_Value_Literal_Acc)
1998   is
1999      Aggr_Type : constant Iir := Get_Type (Aggregate);
2000      El_Type : constant Iir := Get_Element_Subtype (Aggr_Type);
2001      Index_List : constant Iir_Flist := Get_Index_Subtype_List (Aggr_Type);
2002      Nbr_Dim : constant Iir_Index32 :=
2003        Iir_Index32 (Get_Nbr_Elements (Index_List));
2004      Step : Iir_Index32;
2005   begin
2006      Step := Get_Step_For_Dim (Res, 1);
2007      Fill_Array_Aggregate_1
2008        (Block, Aggregate, Res, 0, Step, 1, Nbr_Dim, El_Type);
2009   end Fill_Array_Aggregate;
2010
2011   function Execute_Record_Aggregate (Block: Block_Instance_Acc;
2012                                      Aggregate: Iir;
2013                                      Aggregate_Type: Iir)
2014                                     return Iir_Value_Literal_Acc
2015   is
2016      List : constant Iir_Flist :=
2017        Get_Elements_Declaration_List (Get_Base_Type (Aggregate_Type));
2018
2019      Res: Iir_Value_Literal_Acc;
2020      Expr : Iir;
2021
2022      procedure Set_Expr (Pos : Iir_Index32) is
2023         El : constant Iir := Get_Nth_Element (List, Natural (Pos - 1));
2024      begin
2025         Res.Val_Record.V (Pos) :=
2026           Execute_Expression_With_Type (Block, Expr, Get_Type (El));
2027      end Set_Expr;
2028
2029      Pos : Iir_Index32;
2030      Assoc: Iir;
2031      N_Expr : Iir;
2032   begin
2033      Res := Create_Record_Value (Iir_Index32 (Get_Nbr_Elements (List)));
2034
2035      Assoc := Get_Association_Choices_Chain (Aggregate);
2036      Pos := 1;
2037      loop
2038         N_Expr := Get_Associated_Expr (Assoc);
2039         if N_Expr /= Null_Iir then
2040            Expr := N_Expr;
2041         end if;
2042         case Get_Kind (Assoc) is
2043            when Iir_Kind_Choice_By_None =>
2044               Set_Expr (Pos);
2045               Pos := Pos + 1;
2046            when Iir_Kind_Choice_By_Name =>
2047               Set_Expr (1 + Get_Element_Position
2048                           (Get_Named_Entity (Get_Choice_Name (Assoc))));
2049            when Iir_Kind_Choice_By_Others =>
2050               for I in Res.Val_Record.V'Range loop
2051                  if Res.Val_Record.V (I) = null then
2052                     Set_Expr (I);
2053                  end if;
2054               end loop;
2055            when others =>
2056               Error_Kind ("execute_record_aggregate", Assoc);
2057         end case;
2058         Assoc := Get_Chain (Assoc);
2059         exit when Assoc = Null_Iir;
2060      end loop;
2061      return Res;
2062   end Execute_Record_Aggregate;
2063
2064   function Execute_Aggregate (Block: Block_Instance_Acc;
2065                               Aggregate: Iir;
2066                               Block_Type : Block_Instance_Acc;
2067                               Aggregate_Type: Iir)
2068                              return Iir_Value_Literal_Acc is
2069   begin
2070      case Get_Kind (Aggregate_Type) is
2071         when Iir_Kind_Array_Type_Definition
2072           | Iir_Kind_Array_Subtype_Definition =>
2073            declare
2074               Res : Iir_Value_Literal_Acc;
2075            begin
2076               Res := Create_Array_Bounds_From_Type
2077                 (Block_Type, Aggregate_Type, True);
2078               Fill_Array_Aggregate (Block, Aggregate, Res);
2079               return Res;
2080            end;
2081         when Iir_Kind_Record_Type_Definition
2082           | Iir_Kind_Record_Subtype_Definition =>
2083            return Execute_Record_Aggregate (Block, Aggregate, Aggregate_Type);
2084         when others =>
2085            Error_Kind ("execute_aggregate", Aggregate_Type);
2086      end case;
2087   end Execute_Aggregate;
2088
2089   function Execute_Association_Expression
2090     (Actual_Instance : Block_Instance_Acc;
2091      Actual : Iir;
2092      Formal_Instance : Block_Instance_Acc)
2093     return Iir_Value_Literal_Acc
2094   is
2095   begin
2096      case Get_Kind (Actual) is
2097         when Iir_Kind_String_Literal8 =>
2098            return Execute_String_Literal (Actual, Formal_Instance);
2099         when Iir_Kind_Aggregate =>
2100            return Execute_Aggregate
2101              (Actual_Instance, Actual, Formal_Instance, Get_Type (Actual));
2102         when others =>
2103            null;
2104      end case;
2105      return Execute_Expression (Actual_Instance, Actual);
2106   end Execute_Association_Expression;
2107
2108
2109   function Execute_Simple_Aggregate (Block: Block_Instance_Acc; Aggr : Iir)
2110                                     return Iir_Value_Literal_Acc
2111   is
2112      Res : Iir_Value_Literal_Acc;
2113      List : constant Iir_Flist := Get_Simple_Aggregate_List (Aggr);
2114   begin
2115      Res := Create_Array_Bounds_From_Type (Block, Get_Type (Aggr), True);
2116      for I in Res.Val_Array.V'Range loop
2117         Res.Val_Array.V (I) :=
2118           Execute_Expression (Block, Get_Nth_Element (List, Natural (I - 1)));
2119      end loop;
2120      return Res;
2121   end Execute_Simple_Aggregate;
2122
2123   --  Fill LENGTH elements of RES, starting at ORIG by steps of STEP.
2124   --  Use expressions from (BLOCK, AGGREGATE) to fill the elements.
2125   --  EL_TYPE is the type of the array element.
2126   procedure Execute_Name_Array_Aggregate (Block : Block_Instance_Acc;
2127                                           Aggregate : Iir;
2128                                           Res : Iir_Value_Literal_Acc;
2129                                           Orig : Iir_Index32;
2130                                           Step : Iir_Index32;
2131                                           Dim : Iir_Index32;
2132                                           Nbr_Dim : Iir_Index32;
2133                                           El_Type : Iir)
2134   is
2135      Value : Iir;
2136      Bound : Iir_Value_Literal_Acc;
2137
2138      procedure Set_Elem (Pos : Iir_Index32)
2139      is
2140         Val : Iir_Value_Literal_Acc;
2141         Is_Sig : Boolean;
2142      begin
2143         if Dim = Nbr_Dim then
2144            --  VALUE is an expression (which may be an aggregate, but not
2145            --  a sub-aggregate.
2146            Execute_Name_With_Base (Block, Value, null, Val, Is_Sig);
2147            Res.Val_Array.V (1 + Orig + Pos * Step) := Val;
2148         else
2149            --  VALUE is a sub-aggregate.
2150            Execute_Name_Array_Aggregate
2151              (Block, Value, Res,
2152               Orig + Pos * Step,
2153               Step / Res.Bounds.D (Dim + 1).Length,
2154               Dim + 1, Nbr_Dim, El_Type);
2155         end if;
2156      end Set_Elem;
2157
2158      Assoc : Iir;
2159      Pos : Iir_Index32;
2160   begin
2161      Assoc := Get_Association_Choices_Chain (Aggregate);
2162      Bound := Res.Bounds.D (Dim);
2163      Pos := 0;
2164      while Assoc /= Null_Iir loop
2165         Value := Get_Associated_Expr (Assoc);
2166         case Get_Kind (Assoc) is
2167            when Iir_Kind_Choice_By_None =>
2168               null;
2169            when Iir_Kind_Choice_By_Expression =>
2170               declare
2171                  Expr_Pos: Iir_Value_Literal_Acc;
2172                  Val : constant Iir := Get_Expression (Assoc);
2173               begin
2174                  Expr_Pos := Execute_Expression (Block, Val);
2175                  Pos := Get_Index_Offset (Expr_Pos, Bound, Val);
2176               end;
2177            when others =>
2178               raise Internal_Error;
2179         end case;
2180         Set_Elem (Pos);
2181         Pos := Pos + 1;
2182         Assoc := Get_Chain (Assoc);
2183      end loop;
2184   end Execute_Name_Array_Aggregate;
2185
2186   function Execute_Record_Name_Aggregate (Block: Block_Instance_Acc;
2187                                           Aggregate: Iir;
2188                                           Aggregate_Type: Iir)
2189                                          return Iir_Value_Literal_Acc
2190   is
2191      List : constant Iir_Flist :=
2192        Get_Elements_Declaration_List (Get_Base_Type (Aggregate_Type));
2193      Res: Iir_Value_Literal_Acc;
2194      Expr : Iir;
2195      Pos : Iir_Index32;
2196      El_Pos : Iir_Index32;
2197      Is_Sig : Boolean;
2198      Assoc: Iir;
2199   begin
2200      Res := Create_Record_Value (Iir_Index32 (Get_Nbr_Elements (List)));
2201      Assoc := Get_Association_Choices_Chain (Aggregate);
2202      Pos := 0;
2203      loop
2204         Expr := Get_Associated_Expr (Assoc);
2205         if Expr = Null_Iir then
2206            --  List of choices is not allowed.
2207            raise Internal_Error;
2208         end if;
2209         case Get_Kind (Assoc) is
2210            when Iir_Kind_Choice_By_None =>
2211               El_Pos := Pos;
2212               Pos := Pos + 1;
2213            when Iir_Kind_Choice_By_Name =>
2214               El_Pos := Get_Element_Position (Get_Name (Assoc));
2215            when Iir_Kind_Choice_By_Others =>
2216               raise Internal_Error;
2217            when others =>
2218               Error_Kind ("execute_record_name_aggregate", Assoc);
2219         end case;
2220         Execute_Name_With_Base
2221           (Block, Expr, null, Res.Val_Record.V (1 + El_Pos), Is_Sig);
2222         Assoc := Get_Chain (Assoc);
2223         exit when Assoc = Null_Iir;
2224      end loop;
2225      return Res;
2226   end Execute_Record_Name_Aggregate;
2227
2228   function Execute_Name_Aggregate (Block: Block_Instance_Acc;
2229                                    Aggregate: Iir;
2230                                    Aggregate_Type: Iir)
2231                                   return Iir_Value_Literal_Acc is
2232   begin
2233      case Get_Kind (Aggregate_Type) is
2234         when Iir_Kind_Array_Type_Definition
2235           | Iir_Kind_Array_Subtype_Definition =>
2236            declare
2237               El_Type : constant Iir := Get_Element_Subtype (Aggregate_Type);
2238               Index_List : constant Iir_Flist :=
2239                 Get_Index_Subtype_List (Aggregate_Type);
2240               Nbr_Dim : constant Iir_Index32 :=
2241                 Iir_Index32 (Get_Nbr_Elements (Index_List));
2242               Res : Iir_Value_Literal_Acc;
2243               Step : Iir_Index32;
2244            begin
2245               pragma Assert
2246                 (Get_Constraint_State (Aggregate_Type) = Fully_Constrained);
2247               Res := Create_Array_Bounds_From_Type
2248                 (Block, Aggregate_Type, True);
2249               Step := Get_Step_For_Dim (Res, 1);
2250               Execute_Name_Array_Aggregate
2251                 (Block, Aggregate, Res, 0, Step, 1, Nbr_Dim, El_Type);
2252               return Res;
2253            end;
2254         when Iir_Kind_Record_Type_Definition
2255           | Iir_Kind_Record_Subtype_Definition =>
2256            return Execute_Record_Name_Aggregate
2257              (Block, Aggregate, Aggregate_Type);
2258         when others =>
2259            Error_Kind ("execute_name_aggregate", Aggregate_Type);
2260      end case;
2261   end Execute_Name_Aggregate;
2262
2263   --  Return the indexes range for prefix of ATTR.
2264   function Execute_Indexes (Block: Block_Instance_Acc; Attr : Iir)
2265                            return Iir_Value_Literal_Acc
2266   is
2267      Prefix : constant Iir := Strip_Denoting_Name (Get_Prefix (Attr));
2268      Dim : constant Natural :=
2269        Vhdl.Evaluation.Eval_Attribute_Parameter_Or_1 (Attr);
2270   begin
2271      case Get_Kind (Prefix) is
2272         when Iir_Kind_Type_Declaration
2273           | Iir_Kind_Subtype_Declaration =>
2274            declare
2275               Index : Iir;
2276            begin
2277               Index := Get_Nth_Element
2278                 (Get_Index_Subtype_List (Get_Type (Prefix)), Dim - 1);
2279               return Execute_Bounds (Block, Index);
2280            end;
2281         when Iir_Kind_Array_Type_Definition
2282           | Iir_Kind_Array_Subtype_Definition =>
2283            Error_Kind ("execute_indexes", Prefix);
2284         when others =>
2285            declare
2286               Orig : Iir_Value_Literal_Acc;
2287            begin
2288               Orig := Execute_Name (Block, Prefix, True);
2289               return Orig.Bounds.D (Iir_Index32 (Dim));
2290            end;
2291      end case;
2292   end Execute_Indexes;
2293
2294   function Execute_Bounds (Block: Block_Instance_Acc; Prefix: Iir)
2295      return Iir_Value_Literal_Acc
2296   is
2297      Bound : Iir_Value_Literal_Acc;
2298   begin
2299      case Get_Kind (Prefix) is
2300         when Iir_Kind_Range_Expression =>
2301            declare
2302               Info : constant Sim_Info_Acc := Get_Info (Prefix);
2303            begin
2304               if Info = null then
2305                  Bound := Create_Range_Value
2306                    (Execute_Expression (Block, Get_Left_Limit (Prefix)),
2307                     Execute_Expression (Block, Get_Right_Limit (Prefix)),
2308                     Get_Direction (Prefix));
2309               elsif Info.Kind = Kind_Object then
2310                  Bound := Get_Instance_Object (Block, Prefix);
2311               else
2312                  raise Internal_Error;
2313               end if;
2314            end;
2315
2316         when Iir_Kind_Subtype_Declaration =>
2317            return Execute_Bounds (Block, Get_Type (Prefix));
2318
2319         when Iir_Kind_Integer_Subtype_Definition
2320           | Iir_Kind_Floating_Subtype_Definition
2321           | Iir_Kind_Enumeration_Subtype_Definition
2322           | Iir_Kind_Enumeration_Type_Definition
2323           | Iir_Kind_Physical_Subtype_Definition =>
2324            --  FIXME: move this block before and avoid recursion.
2325            return Execute_Bounds (Block, Get_Range_Constraint (Prefix));
2326
2327         when Iir_Kind_Range_Array_Attribute =>
2328            Bound := Execute_Indexes (Block, Prefix);
2329         when Iir_Kind_Reverse_Range_Array_Attribute =>
2330            Bound := Execute_Indexes (Block, Prefix);
2331            case Bound.Dir is
2332               when Dir_To =>
2333                  Bound := Create_Range_Value
2334                    (Bound.Right, Bound.Left, Dir_Downto, Bound.Length);
2335               when Dir_Downto =>
2336                  Bound := Create_Range_Value
2337                    (Bound.Right, Bound.Left, Dir_To, Bound.Length);
2338            end case;
2339
2340         when Iir_Kind_Floating_Type_Definition
2341           | Iir_Kind_Integer_Type_Definition =>
2342            return Execute_Bounds
2343              (Block,
2344               Get_Range_Constraint (Get_Type (Get_Type_Declarator (Prefix))));
2345
2346         when Iir_Kinds_Denoting_Name =>
2347            return Execute_Bounds (Block, Get_Named_Entity (Prefix));
2348
2349         when Iir_Kind_Subtype_Attribute =>
2350            return Execute_Bounds (Block, Get_Type (Prefix));
2351
2352         when others =>
2353            -- Error_Kind ("execute_bounds", Get_Kind (Prefix));
2354            declare
2355               Prefix_Val: Iir_Value_Literal_Acc;
2356            begin
2357               Prefix_Val := Execute_Expression (Block, Prefix);
2358               Bound := Prefix_Val.Bounds.D (1);
2359            end;
2360      end case;
2361      if not Bound.Dir'Valid then
2362         raise Internal_Error;
2363      end if;
2364      return Bound;
2365   end Execute_Bounds;
2366
2367   -- Perform type conversion as desribed in LRM93 7.3.5
2368   function Execute_Type_Conversion (Block: Block_Instance_Acc;
2369                                     Val : Iir_Value_Literal_Acc;
2370                                     Target_Type : Iir;
2371                                     Loc : Iir)
2372                                    return Iir_Value_Literal_Acc
2373   is
2374      Res: Iir_Value_Literal_Acc;
2375   begin
2376      Res := Val;
2377      case Get_Kind (Target_Type) is
2378         when Iir_Kind_Integer_Type_Definition
2379           | Iir_Kind_Integer_Subtype_Definition =>
2380            case Iir_Value_Numerics (Res.Kind) is
2381               when Iir_Value_I64 =>
2382                  null;
2383               when Iir_Value_F64 =>
2384                  if Res.F64 > Ghdl_F64 (Int64'Last) or
2385                    Res.F64 < Ghdl_F64 (Int64'First)
2386                  then
2387                     Error_Msg_Constraint (Loc);
2388                  end if;
2389                  Res := Create_I64_Value (Ghdl_I64 (Res.F64));
2390            end case;
2391         when Iir_Kind_Floating_Type_Definition
2392           | Iir_Kind_Floating_Subtype_Definition =>
2393            case Iir_Value_Numerics (Res.Kind) is
2394               when Iir_Value_F64 =>
2395                  null;
2396               when Iir_Value_I64 =>
2397                  Res := Create_F64_Value (Ghdl_F64 (Res.I64));
2398            end case;
2399         when Iir_Kind_Enumeration_Type_Definition
2400           | Iir_Kind_Enumeration_Subtype_Definition =>
2401            --  Must be same type.
2402            null;
2403         when Iir_Kind_Physical_Type_Definition
2404           | Iir_Kind_Physical_Subtype_Definition =>
2405            --  Same type.
2406            null;
2407         when Iir_Kind_Record_Type_Definition
2408           | Iir_Kind_Record_Subtype_Definition =>
2409            --  Same type.
2410            null;
2411         when Iir_Kind_Array_Subtype_Definition
2412           | Iir_Kind_Array_Type_Definition =>
2413            --  LRM93 7.3.5
2414            --  if the type mark denotes an unconstrained array type and the
2415            --  operand is not a null array, then for each index position, the
2416            --  bounds of the result are obtained by converting the bounds of
2417            --  the operand to the corresponding index type of the target type.
2418            --
2419            --  LRM93 7.3.5
2420            --  If the type mark denotes a constrained array subtype, then the
2421            --  bounds of the result are those imposed by the type mark.
2422            if Get_Constraint_State (Target_Type) = Fully_Constrained then
2423               Implicit_Array_Conversion (Block, Res, Target_Type, Loc);
2424            else
2425               declare
2426                  Idx_List : constant Iir_Flist :=
2427                    Get_Index_Subtype_List (Target_Type);
2428                  Idx_Type : Iir;
2429               begin
2430                  Res := Create_Array_Value (Val.Bounds.Nbr_Dims);
2431                  Res.Val_Array := Val.Val_Array;
2432                  for I in Val.Bounds.D'Range loop
2433                     Idx_Type := Get_Index_Type (Idx_List, Natural (I - 1));
2434                     Res.Bounds.D (I) := Create_Range_Value
2435                       (Left => Execute_Type_Conversion
2436                          (Block, Val.Bounds.D (I).Left, Idx_Type, Loc),
2437                        Right => Execute_Type_Conversion
2438                          (Block, Val.Bounds.D (I).Right, Idx_Type, Loc),
2439                        Dir => Val.Bounds.D (I).Dir,
2440                        Length => Val.Bounds.D (I).Length);
2441                  end loop;
2442               end;
2443               end if;
2444         when others =>
2445            Error_Kind ("execute_type_conversion", Target_Type);
2446      end case;
2447      Check_Constraints (Block, Res, Target_Type, Loc);
2448      return Res;
2449   end Execute_Type_Conversion;
2450
2451   --  Decrement VAL.
2452   --  May raise a constraint error using EXPR.
2453   function Execute_Dec (Val : Iir_Value_Literal_Acc; Expr : Iir)
2454     return Iir_Value_Literal_Acc
2455   is
2456      Res : Iir_Value_Literal_Acc;
2457   begin
2458      case Iir_Value_Discrete (Val.Kind) is
2459         when Iir_Value_B1 =>
2460            if Val.B1 = False then
2461               Error_Msg_Constraint (Expr);
2462            end if;
2463            Res := Create_B1_Value (False);
2464         when Iir_Value_E8 =>
2465            if Val.E8 = 0 then
2466               Error_Msg_Constraint (Expr);
2467            end if;
2468            Res := Create_E8_Value (Val.E8 - 1);
2469         when Iir_Value_E32 =>
2470            if Val.E32 = 0 then
2471               Error_Msg_Constraint (Expr);
2472            end if;
2473            Res := Create_E32_Value (Val.E32 - 1);
2474         when Iir_Value_I64 =>
2475            if Val.I64 = Ghdl_I64'First then
2476               Error_Msg_Constraint (Expr);
2477            end if;
2478            Res := Create_I64_Value (Val.I64 - 1);
2479      end case;
2480      return Res;
2481   end Execute_Dec;
2482
2483   --  Increment VAL.
2484   --  May raise a constraint error using EXPR.
2485   function Execute_Inc (Val : Iir_Value_Literal_Acc; Expr : Iir)
2486     return Iir_Value_Literal_Acc
2487   is
2488      Res : Iir_Value_Literal_Acc;
2489   begin
2490      case Iir_Value_Discrete (Val.Kind) is
2491         when Iir_Value_B1 =>
2492            if Val.B1 = True then
2493               Error_Msg_Constraint (Expr);
2494            end if;
2495            Res := Create_B1_Value (True);
2496         when Iir_Value_E32 =>
2497            if Val.E32 = Ghdl_E32'Last then
2498               Error_Msg_Constraint (Expr);
2499            end if;
2500            Res := Create_E32_Value (Val.E32 + 1);
2501         when Iir_Value_E8 =>
2502            if Val.E8 = Ghdl_E8'Last then
2503               Error_Msg_Constraint (Expr);
2504            end if;
2505            Res := Create_E8_Value (Val.E8 + 1);
2506         when Iir_Value_I64 =>
2507            if Val.I64 = Ghdl_I64'Last then
2508               Error_Msg_Constraint (Expr);
2509            end if;
2510            Res := Create_I64_Value (Val.I64 + 1);
2511      end case;
2512      return Res;
2513   end Execute_Inc;
2514
2515   function Execute_Expression_With_Type (Block: Block_Instance_Acc;
2516                                          Expr: Iir;
2517                                          Expr_Type : Iir)
2518                                         return Iir_Value_Literal_Acc
2519   is
2520      Res : Iir_Value_Literal_Acc;
2521   begin
2522      if Get_Kind (Expr) = Iir_Kind_Aggregate
2523        and then not Is_Fully_Constrained_Type (Get_Type (Expr))
2524      then
2525         return Execute_Aggregate (Block, Expr, Block, Expr_Type);
2526      else
2527         Res := Execute_Expression (Block, Expr);
2528         Implicit_Array_Conversion (Block, Res, Expr_Type, Expr);
2529         Check_Constraints (Block, Res, Expr_Type, Expr);
2530         return Res;
2531      end if;
2532   end Execute_Expression_With_Type;
2533
2534   function Execute_Signal_Name
2535     (Block : Block_Instance_Acc; Expr : Iir; Kind : Signal_Slot)
2536     return Iir_Value_Literal_Acc
2537   is
2538      Base : constant Iir := Get_Object_Prefix (Expr, False);
2539      Info : constant Sim_Info_Acc := Get_Info (Base);
2540      Bblk : Block_Instance_Acc;
2541      Slot : Object_Slot_Type;
2542      Base_Val : Iir_Value_Literal_Acc;
2543      Res : Iir_Value_Literal_Acc;
2544      Is_Sig : Boolean;
2545   begin
2546      if Get_Kind (Base) = Iir_Kind_Object_Alias_Declaration then
2547         Bblk := Get_Instance_By_Scope (Block, Info.Obj_Scope);
2548         Base_Val := Execute_Signal_Name (Bblk, Get_Name (Base), Kind);
2549      else
2550         Bblk := Get_Instance_By_Scope (Block, Info.Obj_Scope);
2551         case Kind is
2552            when Signal_Sig =>
2553               Slot := Info.Slot;
2554            when Signal_Val =>
2555               Slot := Info.Slot + 1;
2556            when Signal_Init =>
2557               Slot := Info.Slot + 2;
2558         end case;
2559         Base_Val := Bblk.Objects (Slot);
2560      end if;
2561      Execute_Name_With_Base (Block, Expr, Base_Val, Res, Is_Sig);
2562      pragma Assert (Is_Sig);
2563      return Res;
2564   end Execute_Signal_Name;
2565
2566   --  Indexed element will be at Pfx.Val_Array.V (Pos + 1)
2567   procedure Execute_Indexed_Name (Block: Block_Instance_Acc;
2568                                   Expr: Iir;
2569                                   Pfx : Iir_Value_Literal_Acc;
2570                                   Pos : out Iir_Index32)
2571   is
2572      pragma Assert (Get_Kind (Expr) = Iir_Kind_Indexed_Name);
2573      Index_List : constant Iir_Flist := Get_Index_List (Expr);
2574      Nbr_Dimensions : constant Iir_Index32 :=
2575        Iir_Index32 (Get_Nbr_Elements (Index_List));
2576      Index: Iir;
2577      Value: Iir_Value_Literal_Acc;
2578      Off : Iir_Index32;
2579   begin
2580      for I in 1 .. Nbr_Dimensions loop
2581         Index := Get_Nth_Element (Index_List, Natural (I - 1));
2582         Value := Execute_Expression (Block, Index);
2583         Off := Get_Index_Offset (Value, Pfx.Bounds.D (I), Expr);
2584         if I = 1 then
2585            Pos := Off;
2586         else
2587            Pos := Pos * Pfx.Bounds.D (I).Length + Off;
2588         end if;
2589      end loop;
2590   end Execute_Indexed_Name;
2591
2592   --  Indexed element will be at Pfx.Val_Array.V (Pos)
2593   procedure Execute_Slice_Name (Prefix_Array: Iir_Value_Literal_Acc;
2594                                 Srange : Iir_Value_Literal_Acc;
2595                                 Low : out Iir_Index32;
2596                                 High : out Iir_Index32;
2597                                 Loc : Iir)
2598   is
2599      Index_Order : Order;
2600      -- Lower and upper bounds of the slice.
2601   begin
2602      pragma Assert (Prefix_Array /= null);
2603
2604      --  LRM93 6.5
2605      --  It is an error if the direction of the discrete range is not
2606      --  the same as that of the index range of the array denoted by
2607      --  the prefix of the slice name.
2608      if Srange.Dir /= Prefix_Array.Bounds.D (1).Dir then
2609         Error_Msg_Exec ("slice direction mismatch", Loc);
2610      end if;
2611
2612      --  LRM93 6.5
2613      --  It is an error if either of the bounds of the
2614      --  discrete range does not belong to the index range of the
2615      --  prefixing array, unless the slice is a null slice.
2616      Index_Order := Compare_Value (Srange.Left, Srange.Right);
2617      if (Srange.Dir = Dir_To and Index_Order = Greater)
2618        or (Srange.Dir = Dir_Downto and Index_Order = Less)
2619      then
2620         --  Null slice.
2621         Low := 1;
2622         High := 0;
2623      else
2624         Low := Get_Index_Offset
2625           (Srange.Left, Prefix_Array.Bounds.D (1), Loc);
2626         High := Get_Index_Offset
2627           (Srange.Right, Prefix_Array.Bounds.D (1), Loc);
2628      end if;
2629   end Execute_Slice_Name;
2630
2631   procedure Execute_Name_With_Base (Block: Block_Instance_Acc;
2632                                     Expr: Iir;
2633                                     Base : Iir_Value_Literal_Acc;
2634                                     Res : out Iir_Value_Literal_Acc;
2635                                     Is_Sig : out Boolean) is
2636   begin
2637      --  Default value
2638      Is_Sig := False;
2639
2640      case Get_Kind (Expr) is
2641         when Iir_Kind_Interface_Signal_Declaration
2642           | Iir_Kind_Signal_Declaration
2643           | Iir_Kind_Guard_Signal_Declaration
2644           | Iir_Kind_Stable_Attribute
2645           | Iir_Kind_Quiet_Attribute
2646           | Iir_Kind_Delayed_Attribute
2647           | Iir_Kind_Transaction_Attribute =>
2648            Is_Sig := True;
2649            if Base /= null then
2650               Res := Base;
2651            else
2652               Res := Get_Instance_Object (Block, Expr);
2653            end if;
2654
2655         when Iir_Kind_Object_Alias_Declaration =>
2656            --  FIXME: add a flag ?
2657            Is_Sig := Is_Signal_Object (Expr);
2658            if Base /= null then
2659               Res := Base;
2660            else
2661               Res := Get_Instance_Object (Block, Expr);
2662            end if;
2663
2664         when Iir_Kind_Interface_Constant_Declaration
2665           | Iir_Kind_Constant_Declaration
2666           | Iir_Kind_Interface_Variable_Declaration
2667           | Iir_Kind_Variable_Declaration
2668           | Iir_Kind_Interface_File_Declaration
2669           | Iir_Kind_File_Declaration
2670           | Iir_Kind_Attribute_Value
2671           | Iir_Kind_Iterator_Declaration
2672           | Iir_Kind_Terminal_Declaration
2673           | Iir_Kinds_Quantity_Declaration
2674           | Iir_Kind_Psl_Endpoint_Declaration =>
2675            if Base /= null then
2676               Res := Base;
2677            else
2678               Res := Get_Instance_Object (Block, Expr);
2679            end if;
2680
2681         when Iir_Kind_Indexed_Name =>
2682            declare
2683               Pfx : Iir_Value_Literal_Acc;
2684               Pos : Iir_Index32;
2685            begin
2686               Execute_Name_With_Base
2687                 (Block, Get_Prefix (Expr), Base, Pfx, Is_Sig);
2688               Execute_Indexed_Name (Block, Expr, Pfx, Pos);
2689               Res := Pfx.Val_Array.V (Pos + 1);
2690            end;
2691
2692         when Iir_Kind_Slice_Name =>
2693            declare
2694               Prefix_Array: Iir_Value_Literal_Acc;
2695               Srange : Iir_Value_Literal_Acc;
2696               Low, High: Iir_Index32;
2697            begin
2698               Execute_Name_With_Base
2699                 (Block, Get_Prefix (Expr), Base, Prefix_Array, Is_Sig);
2700
2701               Srange := Execute_Bounds (Block, Get_Suffix (Expr));
2702               Execute_Slice_Name (Prefix_Array, Srange, Low, High, Expr);
2703
2704               Res := Create_Array_Value (High - Low + 1, 1);
2705               Res.Bounds.D (1) := Srange;
2706               for I in Low .. High loop
2707                  Res.Val_Array.V (1 + I - Low) :=
2708                    Prefix_Array.Val_Array.V (1 + I);
2709               end loop;
2710            end;
2711
2712         when Iir_Kind_Selected_Element =>
2713            declare
2714               Prefix: Iir_Value_Literal_Acc;
2715               Pos: Iir_Index32;
2716            begin
2717               Execute_Name_With_Base
2718                 (Block, Get_Prefix (Expr), Base, Prefix, Is_Sig);
2719               Pos := Get_Element_Position (Get_Named_Entity (Expr));
2720               Res := Prefix.Val_Record.V (Pos + 1);
2721            end;
2722
2723         when Iir_Kind_Dereference
2724           | Iir_Kind_Implicit_Dereference =>
2725            declare
2726               Prefix: Iir_Value_Literal_Acc;
2727            begin
2728               Prefix := Execute_Name (Block, Get_Prefix (Expr));
2729               Res := Prefix.Val_Access;
2730               if Res = null then
2731                  Error_Msg_Exec ("deferencing null access", Expr);
2732               end if;
2733            end;
2734
2735         when Iir_Kinds_Denoting_Name
2736           | Iir_Kind_Attribute_Name =>
2737            Execute_Name_With_Base
2738              (Block, Get_Named_Entity (Expr), Base, Res, Is_Sig);
2739
2740         when Iir_Kind_Function_Call =>
2741            --  A prefix can be an expression
2742            if Base /= null then
2743               raise Internal_Error;
2744            end if;
2745            Res := Execute_Expression (Block, Expr);
2746
2747         when Iir_Kind_Aggregate =>
2748            Res := Execute_Name_Aggregate (Block, Expr, Get_Type (Expr));
2749
2750         when Iir_Kind_Image_Attribute =>
2751            Res := Execute_Image_Attribute (Block, Expr);
2752
2753         when Iir_Kind_Path_Name_Attribute
2754           | Iir_Kind_Instance_Name_Attribute =>
2755            Res := Execute_Path_Instance_Name_Attribute (Block, Expr);
2756
2757         when others =>
2758            Error_Kind ("execute_name_with_base", Expr);
2759      end case;
2760   end Execute_Name_With_Base;
2761
2762   function Execute_Name (Block: Block_Instance_Acc;
2763                          Expr: Iir;
2764                          Ref : Boolean := False)
2765                         return Iir_Value_Literal_Acc
2766   is
2767      Res: Iir_Value_Literal_Acc;
2768      Is_Sig : Boolean;
2769   begin
2770      Execute_Name_With_Base (Block, Expr, null, Res, Is_Sig);
2771      if not Is_Sig or else Ref then
2772         return Res;
2773      else
2774         return Execute_Signal_Value (Res);
2775      end if;
2776   end Execute_Name;
2777
2778   function Execute_Value_Attribute (Block: Block_Instance_Acc;
2779                                     Str_Val : Iir_Value_Literal_Acc;
2780                                     Expr: Iir)
2781                                    return Iir_Value_Literal_Acc
2782   is
2783      use Grt_Interface;
2784      use Name_Table;
2785      pragma Unreferenced (Block);
2786
2787      Expr_Type : constant Iir := Get_Type (Expr);
2788      Res : Iir_Value_Literal_Acc;
2789
2790      Str_Bnd : aliased Std_String_Bound := Build_Bound (Str_Val);
2791      Str_Str : aliased Std_String_Uncons (1 .. Str_Bnd.Dim_1.Length);
2792      Str : aliased Std_String := (To_Std_String_Basep (Str_Str'Address),
2793                                   To_Std_String_Boundp (Str_Bnd'Address));
2794   begin
2795      Set_Std_String_From_Iir_Value (Str, Str_Val);
2796      case Get_Kind (Expr_Type) is
2797         when Iir_Kind_Integer_Type_Definition
2798           | Iir_Kind_Integer_Subtype_Definition =>
2799            Res := Create_I64_Value
2800              (Grt.Values.Ghdl_Value_I64 (Str'Unrestricted_Access));
2801         when Iir_Kind_Floating_Type_Definition
2802           | Iir_Kind_Floating_Subtype_Definition =>
2803            Res := Create_F64_Value
2804              (Grt.Values.Ghdl_Value_F64 (Str'Unrestricted_Access));
2805         when Iir_Kind_Physical_Type_Definition
2806           | Iir_Kind_Physical_Subtype_Definition =>
2807            declare
2808               Is_Real : Boolean;
2809               Lit_Pos : Ghdl_Index_Type;
2810               Lit_End : Ghdl_Index_Type;
2811               Unit_Pos : Ghdl_Index_Type;
2812               Unit_Len : Ghdl_Index_Type;
2813               Mult : Ghdl_I64;
2814               Unit : Iir;
2815               Unit_Id : Name_Id;
2816            begin
2817               Grt.Values.Ghdl_Value_Physical_Split
2818                 (Str'Unrestricted_Access,
2819                  Is_Real, Lit_Pos, Lit_End, Unit_Pos);
2820
2821               --  Find unit.
2822               Unit_Len := 0;
2823               Unit_Pos := Unit_Pos + 1;   --  From 0 based to 1 based
2824               for I in Unit_Pos .. Str_Bnd.Dim_1.Length loop
2825                  exit when Grt.Strings.Is_Whitespace (Str_Str (I));
2826                  Unit_Len := Unit_Len + 1;
2827                  Str_Str (I) := Grt.Strings.To_Lower (Str_Str (I));
2828               end loop;
2829
2830               Unit := Get_Primary_Unit (Expr_Type);
2831               while Unit /= Null_Iir loop
2832                  Unit_Id := Get_Identifier (Unit);
2833                  exit when Get_Name_Length (Unit_Id) = Natural (Unit_Len)
2834                    and then Image (Unit_Id) =
2835                    String (Str_Str (Unit_Pos .. Unit_Pos + Unit_Len - 1));
2836                  Unit := Get_Chain (Unit);
2837               end loop;
2838
2839               if Unit = Null_Iir then
2840                  Error_Msg_Exec ("incorrect unit name", Expr);
2841               end if;
2842               Mult := Ghdl_I64 (Get_Value (Get_Physical_Literal (Unit)));
2843
2844               Str_Bnd.Dim_1.Length := Lit_End;
2845               if Is_Real then
2846                  Res := Create_I64_Value
2847                    (Ghdl_I64
2848                       (Grt.Values.Ghdl_Value_F64 (Str'Unrestricted_Access)
2849                          * Ghdl_F64 (Mult)));
2850               else
2851                  Res := Create_I64_Value
2852                    (Grt.Values.Ghdl_Value_I64 (Str'Unrestricted_Access)
2853                       * Mult);
2854               end if;
2855            end;
2856         when Iir_Kind_Enumeration_Type_Definition
2857           | Iir_Kind_Enumeration_Subtype_Definition =>
2858            declare
2859               Enums : constant Iir_Flist :=
2860                 Get_Enumeration_Literal_List (Get_Base_Type (Expr_Type));
2861               Lit_Start : Ghdl_Index_Type;
2862               Lit_End : Ghdl_Index_Type;
2863               Enum : Iir;
2864               Lit_Id : Name_Id;
2865               Enum_Id : Name_Id;
2866            begin
2867               --  Remove leading and trailing blanks
2868               for I in Str_Str'Range loop
2869                  if not Grt.Strings.Is_Whitespace (Str_Str (I)) then
2870                     Lit_Start := I;
2871                     exit;
2872                  end if;
2873               end loop;
2874               for I in reverse Lit_Start .. Str_Str'Last loop
2875                  if not Grt.Strings.Is_Whitespace (Str_Str (I)) then
2876                     Lit_End := I;
2877                     exit;
2878                  end if;
2879               end loop;
2880
2881               if Str_Str (Lit_Start) = '''
2882                 and then Str_Str (Lit_End) = '''
2883                 and then Lit_End = Lit_Start + 2
2884               then
2885                  --  Enumeration literal.
2886                  Lit_Id := Get_Identifier (Str_Str (Lit_Start + 1));
2887
2888                  for I in Natural loop
2889                     Enum := Get_Nth_Element (Enums, I);
2890                     exit when Enum = Null_Iir;
2891                     exit when Get_Identifier (Enum) = Lit_Id;
2892                  end loop;
2893               else
2894                  --  Literal identifier.
2895                  --  Convert to lower case.
2896                  for I in Lit_Start .. Lit_End loop
2897                     Str_Str (I) := Grt.Strings.To_Lower (Str_Str (I));
2898                  end loop;
2899
2900                  for I in Natural loop
2901                     Enum := Get_Nth_Element (Enums, I);
2902                     exit when Enum = Null_Iir;
2903                     Enum_Id := Get_Identifier (Enum);
2904                     exit when (Get_Name_Length (Enum_Id) =
2905                                  Natural (Lit_End - Lit_Start + 1))
2906                       and then (Image (Enum_Id) =
2907                                   String (Str_Str (Lit_Start .. Lit_End)));
2908                  end loop;
2909               end if;
2910
2911               if Enum = Null_Iir then
2912                  Error_Msg_Exec
2913                    ("incorrect enumeration literal for 'value", Expr);
2914               end if;
2915
2916               return Create_Enum_Value
2917                 (Natural (Get_Enum_Pos (Enum)), Expr_Type);
2918            end;
2919         when others =>
2920            Error_Kind ("value_attribute", Expr_Type);
2921      end case;
2922      return Res;
2923   end Execute_Value_Attribute;
2924
2925   --  For 'Last_Event and 'Last_Active: convert the absolute last time to
2926   --  a relative delay.
2927   function To_Relative_Time (T : Ghdl_I64) return Iir_Value_Literal_Acc
2928   is
2929      A : Ghdl_I64;
2930   begin
2931      if T = -Ghdl_I64'Last then
2932         A := Ghdl_I64'Last;
2933      else
2934         A := Ghdl_I64 (Grt.Types.Current_Time) - T;
2935      end if;
2936      return Create_I64_Value (A);
2937   end To_Relative_Time;
2938
2939   -- Evaluate an expression.
2940   function Execute_Expression (Block: Block_Instance_Acc; Expr: Iir)
2941                               return Iir_Value_Literal_Acc
2942   is
2943      Res: Iir_Value_Literal_Acc;
2944   begin
2945      case Get_Kind (Expr) is
2946         when Iir_Kind_Interface_Signal_Declaration
2947           | Iir_Kind_Signal_Declaration
2948           | Iir_Kind_Guard_Signal_Declaration
2949           | Iir_Kind_Stable_Attribute
2950           | Iir_Kind_Quiet_Attribute
2951           | Iir_Kind_Delayed_Attribute
2952           | Iir_Kind_Transaction_Attribute
2953           | Iir_Kind_Object_Alias_Declaration =>
2954            Res := Execute_Name (Block, Expr);
2955            return Res;
2956
2957         when Iir_Kind_Interface_Constant_Declaration
2958           | Iir_Kind_Constant_Declaration
2959           | Iir_Kind_Interface_Variable_Declaration
2960           | Iir_Kind_Variable_Declaration
2961           | Iir_Kind_Interface_File_Declaration
2962           | Iir_Kind_File_Declaration
2963           | Iir_Kind_Attribute_Value
2964           | Iir_Kind_Iterator_Declaration
2965           | Iir_Kind_Indexed_Name
2966           | Iir_Kind_Slice_Name
2967           | Iir_Kind_Selected_Element
2968           | Iir_Kind_Dereference
2969           | Iir_Kind_Implicit_Dereference
2970           | Iir_Kind_Psl_Endpoint_Declaration =>
2971            return Execute_Name (Block, Expr);
2972
2973         when Iir_Kinds_Denoting_Name
2974           | Iir_Kind_Attribute_Name =>
2975            return Execute_Expression (Block, Get_Named_Entity (Expr));
2976
2977         when Iir_Kind_Aggregate =>
2978            return Execute_Aggregate (Block, Expr, Block, Get_Type (Expr));
2979         when Iir_Kind_Simple_Aggregate =>
2980            return Execute_Simple_Aggregate (Block, Expr);
2981
2982         when Iir_Kinds_Dyadic_Operator
2983           | Iir_Kinds_Monadic_Operator =>
2984            declare
2985               Imp : constant Iir := Get_Implementation (Expr);
2986            begin
2987               if Get_Implicit_Definition (Imp) in Iir_Predefined_Explicit then
2988                  return Execute_Function_Call (Block, Expr, Imp);
2989               else
2990                  if Get_Kind (Expr) in Iir_Kinds_Dyadic_Operator then
2991                     Res := Execute_Implicit_Function
2992                       (Block, Expr, Get_Left (Expr), Get_Right (Expr),
2993                        Get_Type (Expr));
2994                  else
2995                     Res := Execute_Implicit_Function
2996                       (Block, Expr, Get_Operand (Expr), Null_Iir,
2997                        Get_Type (Expr));
2998                  end if;
2999                  return Res;
3000               end if;
3001            end;
3002
3003         when Iir_Kind_Function_Call =>
3004            declare
3005               Imp : constant Iir := Get_Implementation (Expr);
3006               Assoc : Iir;
3007               Args : Iir_Array (0 .. 1);
3008            begin
3009               if Get_Implicit_Definition (Imp) in Iir_Predefined_Explicit then
3010                  return Execute_Function_Call (Block, Expr, Imp);
3011               else
3012                  Assoc := Get_Parameter_Association_Chain (Expr);
3013                  if Assoc /= Null_Iir then
3014                     Args (0) := Get_Actual (Assoc);
3015                     Assoc := Get_Chain (Assoc);
3016                  else
3017                     Args (0) := Null_Iir;
3018                  end if;
3019                  if Assoc /= Null_Iir  then
3020                     Args (1) := Get_Actual (Assoc);
3021                  else
3022                     Args (1) := Null_Iir;
3023                  end if;
3024                  return Execute_Implicit_Function
3025                    (Block, Expr, Args (0), Args (1), Get_Type (Expr));
3026               end if;
3027            end;
3028
3029         when Iir_Kind_Integer_Literal =>
3030            declare
3031               Lit_Type : constant Iir := Get_Base_Type (Get_Type (Expr));
3032               Lit : constant Int64 := Get_Value (Expr);
3033            begin
3034               case Get_Info (Lit_Type).Kind is
3035                  when Kind_I64_Type =>
3036                     return Create_I64_Value (Ghdl_I64 (Lit));
3037                  when others =>
3038                     raise Internal_Error;
3039               end case;
3040            end;
3041
3042         when Iir_Kind_Floating_Point_Literal =>
3043            return Create_F64_Value (Ghdl_F64 (Get_Fp_Value (Expr)));
3044
3045         when Iir_Kind_Enumeration_Literal =>
3046            return Create_Enum_Value (Natural (Get_Enum_Pos (Expr)),
3047                                      Get_Type (Expr));
3048
3049         when Iir_Kind_Physical_Int_Literal
3050           | Iir_Kind_Physical_Fp_Literal
3051           | Iir_Kind_Unit_Declaration =>
3052            return Create_I64_Value
3053              (Ghdl_I64 (Vhdl.Evaluation.Get_Physical_Value (Expr)));
3054
3055         when Iir_Kind_String_Literal8 =>
3056            return Execute_String_Literal (Expr, Block);
3057
3058         when Iir_Kind_Null_Literal =>
3059            return Null_Lit;
3060
3061         when Iir_Kind_Overflow_Literal =>
3062            Error_Msg_Constraint (Expr);
3063            return null;
3064
3065         when Iir_Kind_Parenthesis_Expression =>
3066            return Execute_Expression (Block, Get_Expression (Expr));
3067
3068         when Iir_Kind_Type_Conversion =>
3069            return Execute_Type_Conversion
3070              (Block, Execute_Expression (Block, Get_Expression (Expr)),
3071               Get_Type (Expr), Expr);
3072
3073         when Iir_Kind_Qualified_Expression =>
3074            Res := Execute_Expression_With_Type
3075              (Block, Get_Expression (Expr), Get_Type (Get_Type_Mark (Expr)));
3076            return Res;
3077
3078         when Iir_Kind_Allocator_By_Expression =>
3079            Res := Execute_Expression (Block, Get_Expression (Expr));
3080            Res := Unshare_Heap (Res);
3081            return Create_Access_Value (Res);
3082
3083         when Iir_Kind_Allocator_By_Subtype =>
3084            Res := Create_Value_For_Type
3085              (Block,
3086               Get_Type_Of_Subtype_Indication (Get_Subtype_Indication (Expr)),
3087               Init_Value_Default);
3088            Res := Unshare_Heap (Res);
3089            return Create_Access_Value (Res);
3090
3091         when Iir_Kind_Left_Type_Attribute =>
3092            Res := Execute_Bounds (Block, Get_Prefix (Expr));
3093            return Execute_Left_Limit (Res);
3094
3095         when Iir_Kind_Right_Type_Attribute =>
3096            Res := Execute_Bounds (Block, Get_Prefix (Expr));
3097            return Execute_Right_Limit (Res);
3098
3099         when Iir_Kind_High_Type_Attribute =>
3100            Res := Execute_Bounds (Block, Get_Prefix (Expr));
3101            return Execute_High_Limit (Res);
3102
3103         when Iir_Kind_Low_Type_Attribute =>
3104            Res := Execute_Bounds (Block, Get_Prefix (Expr));
3105            return Execute_Low_Limit (Res);
3106
3107         when Iir_Kind_High_Array_Attribute =>
3108            Res := Execute_Indexes (Block, Expr);
3109            return Execute_High_Limit (Res);
3110
3111         when Iir_Kind_Low_Array_Attribute =>
3112            Res := Execute_Indexes (Block, Expr);
3113            return Execute_Low_Limit (Res);
3114
3115         when Iir_Kind_Left_Array_Attribute =>
3116            Res := Execute_Indexes (Block, Expr);
3117            return Execute_Left_Limit (Res);
3118
3119         when Iir_Kind_Right_Array_Attribute =>
3120            Res := Execute_Indexes (Block, Expr);
3121            return Execute_Right_Limit (Res);
3122
3123         when Iir_Kind_Length_Array_Attribute =>
3124            Res := Execute_Indexes (Block, Expr);
3125            return Execute_Length (Res);
3126
3127         when Iir_Kind_Ascending_Array_Attribute =>
3128            Res := Execute_Indexes (Block, Expr);
3129            return Boolean_To_Lit (Res.Dir = Dir_To);
3130
3131         when Iir_Kind_Event_Attribute =>
3132            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3133            return Boolean_To_Lit (Execute_Event_Attribute (Res));
3134
3135         when Iir_Kind_Active_Attribute =>
3136            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3137            return Boolean_To_Lit (Execute_Active_Attribute (Res));
3138
3139         when Iir_Kind_Driving_Attribute =>
3140            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3141            return Boolean_To_Lit (Execute_Driving_Attribute (Res));
3142
3143         when Iir_Kind_Last_Value_Attribute =>
3144            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3145            return Execute_Last_Value_Attribute (Res);
3146
3147         when Iir_Kind_Driving_Value_Attribute =>
3148            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3149            return Execute_Driving_Value_Attribute (Res);
3150
3151         when Iir_Kind_Last_Event_Attribute =>
3152            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3153            return To_Relative_Time (Execute_Last_Event_Attribute (Res));
3154
3155         when Iir_Kind_Last_Active_Attribute =>
3156            Res := Execute_Name (Block, Get_Prefix (Expr), True);
3157            return To_Relative_Time (Execute_Last_Active_Attribute (Res));
3158
3159         when Iir_Kind_Val_Attribute =>
3160            declare
3161               Prefix_Type: constant Iir := Get_Type (Get_Prefix (Expr));
3162               Base_Type : constant Iir := Get_Base_Type (Prefix_Type);
3163               Kind : constant Kind_Discrete_Types :=
3164                 Get_Info (Base_Type).Kind;
3165            begin
3166               Res := Execute_Expression (Block, Get_Parameter (Expr));
3167               case Kind is
3168                  when Kind_I64_Type =>
3169                     null;
3170                  when Kind_E8_Type
3171                    | Kind_Log_Type =>
3172                     Res := Create_E8_Value (Ghdl_E8 (Res.I64));
3173                  when Kind_E32_Type =>
3174                     Res := Create_E32_Value (Ghdl_E32 (Res.I64));
3175                  when Kind_Bit_Type =>
3176                     Res := Create_B1_Value (Ghdl_B1'Val (Res.I64));
3177               end case;
3178               Check_Constraints (Block, Res, Prefix_Type, Expr);
3179               return Res;
3180            end;
3181
3182         when Iir_Kind_Pos_Attribute =>
3183            declare
3184               N_Res: Iir_Value_Literal_Acc;
3185               Prefix_Type: constant Iir := Get_Type (Get_Prefix (Expr));
3186               Base_Type : constant Iir := Get_Base_Type (Prefix_Type);
3187               Mode : constant Kind_Discrete_Types :=
3188                 Get_Info (Base_Type).Kind;
3189            begin
3190               Res := Execute_Expression (Block, Get_Parameter (Expr));
3191               case Mode is
3192                  when Kind_I64_Type =>
3193                     null;
3194                  when Kind_Bit_Type =>
3195                     N_Res := Create_I64_Value (Ghdl_B1'Pos (Res.B1));
3196                     Res := N_Res;
3197                  when Kind_E8_Type
3198                    | Kind_Log_Type =>
3199                     N_Res := Create_I64_Value (Ghdl_I64 (Res.E8));
3200                     Res := N_Res;
3201                  when Kind_E32_Type =>
3202                     N_Res := Create_I64_Value (Ghdl_I64 (Res.E32));
3203                     Res := N_Res;
3204               end case;
3205               Check_Constraints (Block, Res, Get_Type (Expr), Expr);
3206               return Res;
3207            end;
3208
3209         when Iir_Kind_Succ_Attribute =>
3210            Res := Execute_Expression (Block, Get_Parameter (Expr));
3211            Res := Execute_Inc (Res, Expr);
3212            Check_Constraints (Block, Res, Get_Type (Expr), Expr);
3213            return Res;
3214
3215         when Iir_Kind_Pred_Attribute =>
3216            Res := Execute_Expression (Block, Get_Parameter (Expr));
3217            Res := Execute_Dec (Res, Expr);
3218            Check_Constraints (Block, Res, Get_Type (Expr), Expr);
3219            return Res;
3220
3221         when Iir_Kind_Leftof_Attribute =>
3222            declare
3223               Bound : Iir_Value_Literal_Acc;
3224            begin
3225               Res := Execute_Expression (Block, Get_Parameter (Expr));
3226               Bound := Execute_Bounds
3227                 (Block, Get_Type (Get_Prefix (Expr)));
3228               case Bound.Dir is
3229                  when Dir_To =>
3230                     Res := Execute_Dec (Res, Expr);
3231                  when Dir_Downto =>
3232                     Res := Execute_Inc (Res, Expr);
3233               end case;
3234               Check_Constraints (Block, Res, Get_Type (Expr), Expr);
3235               return Res;
3236            end;
3237
3238         when Iir_Kind_Rightof_Attribute =>
3239            declare
3240               Bound : Iir_Value_Literal_Acc;
3241            begin
3242               Res := Execute_Expression (Block, Get_Parameter (Expr));
3243               Bound := Execute_Bounds
3244                 (Block, Get_Type (Get_Prefix (Expr)));
3245               case Bound.Dir is
3246                  when Dir_Downto =>
3247                     Res := Execute_Dec (Res, Expr);
3248                  when Dir_To =>
3249                     Res := Execute_Inc (Res, Expr);
3250               end case;
3251               Check_Constraints (Block, Res, Get_Type (Expr), Expr);
3252               return Res;
3253            end;
3254
3255         when Iir_Kind_Image_Attribute =>
3256            return Execute_Image_Attribute (Block, Expr);
3257
3258         when Iir_Kind_Value_Attribute =>
3259            Res := Execute_Expression (Block, Get_Parameter (Expr));
3260            return Execute_Value_Attribute (Block, Res, Expr);
3261
3262         when Iir_Kind_Path_Name_Attribute
3263           | Iir_Kind_Instance_Name_Attribute =>
3264            return Execute_Path_Instance_Name_Attribute (Block, Expr);
3265
3266         when others =>
3267            Error_Kind ("execute_expression", Expr);
3268      end case;
3269   end Execute_Expression;
3270
3271   procedure Execute_Dyadic_Association (Out_Block: Block_Instance_Acc;
3272                                         In_Block: Block_Instance_Acc;
3273                                         Expr : Iir;
3274                                         Inter_Chain: Iir)
3275   is
3276      Inter: Iir;
3277      Val: Iir_Value_Literal_Acc;
3278   begin
3279      Inter := Inter_Chain;
3280      for I in 0 .. 1 loop
3281         if I = 0 then
3282            Val := Execute_Expression (Out_Block, Get_Left (Expr));
3283         else
3284            Val := Execute_Expression (Out_Block, Get_Right (Expr));
3285         end if;
3286         Implicit_Array_Conversion (In_Block, Val, Get_Type (Inter), Expr);
3287         Check_Constraints (In_Block, Val, Get_Type (Inter), Expr);
3288
3289         Elaboration.Create_Object (In_Block, Inter);
3290         In_Block.Objects (Get_Info (Inter).Slot) :=
3291           Unshare (Val, Instance_Pool);
3292         Inter := Get_Chain (Inter);
3293      end loop;
3294   end Execute_Dyadic_Association;
3295
3296   procedure Execute_Monadic_Association (Out_Block: Block_Instance_Acc;
3297                                          In_Block: Block_Instance_Acc;
3298                                          Expr : Iir;
3299                                          Inter: Iir)
3300   is
3301      Val: Iir_Value_Literal_Acc;
3302   begin
3303      Val := Execute_Expression (Out_Block, Get_Operand (Expr));
3304      Implicit_Array_Conversion (In_Block, Val, Get_Type (Inter), Expr);
3305      Check_Constraints (In_Block, Val, Get_Type (Inter), Expr);
3306
3307      Elaboration.Create_Object (In_Block, Inter);
3308      In_Block.Objects (Get_Info (Inter).Slot) :=
3309        Unshare (Val, Instance_Pool);
3310   end Execute_Monadic_Association;
3311
3312   --  Like Get_Protected_Type_Body, but also works for instances, where
3313   --  instantiated nodes have no bodies.
3314   --  FIXME: maybe fix the issue directly in Sem_Inst ?
3315   function Get_Protected_Type_Body_Origin (Spec : Iir) return Iir
3316   is
3317      Res : constant Iir := Get_Protected_Type_Body (Spec);
3318      Orig : Iir;
3319   begin
3320      if Res /= Null_Iir then
3321         return Res;
3322      else
3323         Orig := Vhdl.Sem_Inst.Get_Origin (Spec);
3324         return Get_Protected_Type_Body_Origin (Orig);
3325      end if;
3326   end Get_Protected_Type_Body_Origin;
3327
3328   --  Create a block instance for subprogram IMP.
3329   function Create_Subprogram_Instance (Instance : Block_Instance_Acc;
3330                                        Prot_Obj : Block_Instance_Acc;
3331                                        Imp : Iir)
3332                                       return Block_Instance_Acc
3333   is
3334      Parent : Iir;
3335      Bod : Iir;
3336
3337      Up_Block: Block_Instance_Acc;
3338      Up_Info : Sim_Info_Acc;
3339
3340      Label : Iir;
3341   begin
3342      case Get_Kind (Imp) is
3343         when Iir_Kinds_Subprogram_Declaration =>
3344            Bod := Vhdl.Sem_Inst.Get_Subprogram_Body_Origin (Imp);
3345            Parent := Get_Parent (Imp);
3346            Label := Get_Subprogram_Specification (Bod);
3347         when Iir_Kind_Protected_Type_Declaration =>
3348            --  The parent of the protected type body must have the same scope
3349            --  as the parent of the protected type declaration.
3350            Bod := Get_Protected_Type_Body_Origin (Imp);
3351            Parent := Get_Parent (Get_Type_Declarator (Imp));
3352            Label := Imp;
3353         when others =>
3354            Error_Kind ("create_subprogram_instance", Imp);
3355      end case;
3356
3357      if Prot_Obj /= null then
3358         --  This is a call to a method (from the outside to a subprogram of
3359         --  a protected type). Put the protected object as upblock.
3360         Up_Block := Prot_Obj;
3361      else
3362         --  This is a normal subprogram call.
3363         Up_Info := Get_Info_For_Scope (Parent);
3364         Up_Block := Get_Instance_By_Scope (Instance, Up_Info);
3365      end if;
3366
3367      --  Extract the info from the body, as it is complete (has slot for
3368      --  internal declarations).  Usually, body and spec share the same info,
3369      --  but there are exceptions: there can be multiple spec for the same
3370      --  body for shared generic packages.
3371      declare
3372         Func_Info : constant Sim_Info_Acc := Get_Info (Bod);
3373
3374         subtype Block_Type is Block_Instance_Type (Func_Info.Nbr_Objects);
3375         function To_Block_Instance_Acc is new
3376           Ada.Unchecked_Conversion (System.Address, Block_Instance_Acc);
3377         function Alloc_Block_Instance is new
3378           Alloc_On_Pool_Addr (Block_Type);
3379
3380         Res : Block_Instance_Acc;
3381      begin
3382         Res := To_Block_Instance_Acc
3383           (Alloc_Block_Instance
3384              (Instance_Pool,
3385               Block_Instance_Type'(Max_Objs => Func_Info.Nbr_Objects,
3386                                    Id => No_Block_Instance_Id,
3387                                    Block_Scope => Get_Info (Label),
3388                                    Uninst_Scope => null,
3389                                    Up_Block => Up_Block,
3390                                    Label => Imp,
3391                                    Bod => Bod,
3392                                    Stmt => Null_Iir,
3393                                    Parent => Instance,
3394                                    Children => null,
3395                                    Brother => null,
3396                                    Marker => Empty_Marker,
3397                                    Objects => (others => null),
3398                                    Elab_Objects => 0,
3399                                    In_Wait_Flag => False,
3400                                    Actuals_Ref => null,
3401                                    Result => null)));
3402         return Res;
3403      end;
3404   end Create_Subprogram_Instance;
3405
3406   function Get_Protected_Object_Instance
3407     (Block : Block_Instance_Acc; Call : Iir) return Block_Instance_Acc
3408   is
3409      Meth_Obj : constant Iir := Get_Method_Object (Call);
3410      Obj : Iir_Value_Literal_Acc;
3411   begin
3412      if Meth_Obj = Null_Iir then
3413         return null;
3414      else
3415         Obj := Execute_Name (Block, Meth_Obj, True);
3416         return Protected_Table.Table (Obj.Prot);
3417      end if;
3418   end Get_Protected_Object_Instance;
3419
3420   -- Destroy a dynamic block_instance.
3421   procedure Execute_Subprogram_Call_Final (Instance : Block_Instance_Acc) is
3422   begin
3423      Finalize_Declarative_Part
3424        (Instance, Get_Declaration_Chain (Instance.Bod));
3425   end Execute_Subprogram_Call_Final;
3426
3427   function Execute_Function_Body (Instance : Block_Instance_Acc)
3428                                  return Iir_Value_Literal_Acc
3429   is
3430      Res : Iir_Value_Literal_Acc;
3431   begin
3432      Current_Process.Instance := Instance;
3433
3434      Elaborate_Declarative_Part
3435        (Instance, Get_Declaration_Chain (Instance.Bod));
3436
3437      -- execute statements
3438      Instance.Stmt := Get_Sequential_Statement_Chain (Instance.Bod);
3439      Execute_Sequential_Statements (Current_Process);
3440      pragma Assert (Current_Process.Instance = Instance);
3441
3442      if Instance.Result = null then
3443         Error_Msg_Exec
3444           ("function scope exited without a return statement",
3445            Instance.Label);
3446      end if;
3447
3448      -- Free variables, slots...
3449      -- Need to copy the return value, because it can contains values from
3450      -- arguments.
3451      Res := Instance.Result;
3452
3453      Current_Process.Instance := Instance.Parent;
3454      Execute_Subprogram_Call_Final (Instance);
3455
3456      return Res;
3457   end Execute_Function_Body;
3458
3459   function Execute_Assoc_Function_Conversion (Block : Block_Instance_Acc;
3460                                               Func : Iir;
3461                                               Prot_Block : Block_Instance_Acc;
3462                                               Val : Iir_Value_Literal_Acc)
3463                                              return Iir_Value_Literal_Acc
3464   is
3465      Inter : Iir;
3466      Instance : Block_Instance_Acc;
3467      Res : Iir_Value_Literal_Acc;
3468      Marker : Mark_Type;
3469   begin
3470      Mark (Marker, Instance_Pool.all);
3471
3472      -- Create an instance for this function.
3473      Instance := Create_Subprogram_Instance (Block, Prot_Block, Func);
3474
3475      Inter := Get_Interface_Declaration_Chain (Func);
3476      Elaboration.Create_Object (Instance, Inter);
3477      --  FIXME: implicit conversion
3478      Instance.Objects (Get_Info (Inter).Slot) := Val;
3479
3480      Res := Execute_Function_Body (Instance);
3481      Res := Unshare (Res, Expr_Pool'Access);
3482      Release (Marker, Instance_Pool.all);
3483      return Res;
3484   end Execute_Assoc_Function_Conversion;
3485
3486   function Execute_Assoc_Conversion
3487     (Block : Block_Instance_Acc; Conv : Iir; Val : Iir_Value_Literal_Acc)
3488     return Iir_Value_Literal_Acc
3489   is
3490      Ent : Iir;
3491      Prot_Block : Block_Instance_Acc;
3492   begin
3493      case Get_Kind (Conv) is
3494         when Iir_Kind_Function_Call =>
3495            --  FIXME: shouldn't CONV always be a denoting_name ?
3496            Prot_Block := Get_Protected_Object_Instance (Block, Conv);
3497            return Execute_Assoc_Function_Conversion
3498              (Block, Get_Implementation (Conv), Prot_Block, Val);
3499         when Iir_Kind_Type_Conversion =>
3500            --  FIXME: shouldn't CONV always be a denoting_name ?
3501            return Execute_Type_Conversion (Block, Val, Get_Type (Conv), Conv);
3502         when Iir_Kinds_Denoting_Name
3503           | Iir_Kind_Function_Declaration =>
3504            Ent := Strip_Denoting_Name (Conv);
3505            if Get_Kind (Ent) = Iir_Kind_Function_Declaration then
3506               return Execute_Assoc_Function_Conversion
3507                 (Block, Ent, null, Val);
3508            elsif Get_Kind (Ent) in Iir_Kinds_Type_Declaration then
3509               return Execute_Type_Conversion
3510                 (Block, Val, Get_Type (Ent), Ent);
3511            else
3512               Error_Kind ("execute_assoc_conversion(1)", Ent);
3513            end if;
3514         when others =>
3515            Error_Kind ("execute_assoc_conversion(2)", Conv);
3516      end case;
3517   end Execute_Assoc_Conversion;
3518
3519   procedure Associate_By_Reference (Block : Block_Instance_Acc;
3520                                     Formal : Iir;
3521                                     Formal_Base : Iir_Value_Literal_Acc;
3522                                     Actual : Iir_Value_Literal_Acc)
3523   is
3524      Prefix : constant Iir := Strip_Denoting_Name (Get_Prefix (Formal));
3525      Is_Sig : Boolean;
3526      Pfx : Iir_Value_Literal_Acc;
3527      Pos : Iir_Index32;
3528   begin
3529      if Get_Kind (Prefix) = Iir_Kind_Slice_Name then
3530         --  That case is not handled correctly.
3531         raise Program_Error;
3532      end if;
3533      Execute_Name_With_Base (Block, Prefix, Formal_Base, Pfx, Is_Sig);
3534
3535      case Get_Kind (Formal) is
3536         when Iir_Kind_Indexed_Name =>
3537            Execute_Indexed_Name (Block, Formal, Pfx, Pos);
3538            Store (Pfx.Val_Array.V (Pos + 1), Actual);
3539         when Iir_Kind_Slice_Name =>
3540            declare
3541               Low, High : Iir_Index32;
3542               Srange : Iir_Value_Literal_Acc;
3543            begin
3544               Srange := Execute_Bounds (Block, Get_Suffix (Formal));
3545               Execute_Slice_Name (Pfx, Srange, Low, High, Formal);
3546               for I in 1 .. High - Low + 1 loop
3547                  Store (Pfx.Val_Array.V (Low + I), Actual.Val_Array.V (I));
3548               end loop;
3549            end;
3550         when Iir_Kind_Selected_Element =>
3551            Pos := Get_Element_Position (Get_Named_Entity (Formal));
3552            Store (Pfx.Val_Record.V (Pos + 1), Actual);
3553         when others =>
3554            Error_Kind ("associate_by_reference", Formal);
3555      end case;
3556   end Associate_By_Reference;
3557
3558   --  Establish correspondance for association list ASSOC_LIST from block
3559   --  instance OUT_BLOCK for subprogram of block SUBPRG_BLOCK.
3560   procedure Execute_Association (Out_Block : Block_Instance_Acc;
3561                                  Subprg_Block : Block_Instance_Acc;
3562                                  Inter_Chain : Iir;
3563                                  Assoc_Chain : Iir)
3564   is
3565      Nbr_Assoc : constant Natural := Get_Chain_Length (Assoc_Chain);
3566      Assoc: Iir;
3567      Assoc_Inter : Iir;
3568      Actual : Iir;
3569      Inter: Iir;
3570      Formal : Iir;
3571      Conv : Iir;
3572      Val: Iir_Value_Literal_Acc;
3573      Assoc_Idx : Iir_Index32;
3574      Last_Individual : Iir_Value_Literal_Acc;
3575      Mode : Iir_Mode;
3576      Marker : Mark_Type;
3577   begin
3578      Subprg_Block.Actuals_Ref := null;
3579      Mark (Marker, Expr_Pool);
3580
3581      Assoc := Assoc_Chain;
3582      Assoc_Inter := Inter_Chain;
3583      Assoc_Idx := 1;
3584      while Assoc /= Null_Iir loop
3585         Inter := Get_Association_Interface (Assoc, Assoc_Inter);
3586         Formal := Get_Association_Formal (Assoc, Inter);
3587
3588         --  Extract the actual value.
3589         case Get_Kind (Assoc) is
3590            when Iir_Kind_Association_Element_Open =>
3591               --  Not allowed in individual association.
3592               pragma Assert (Formal = Inter);
3593               pragma Assert (Get_Whole_Association_Flag (Assoc));
3594               Actual := Get_Default_Value (Inter);
3595            when Iir_Kind_Association_Element_By_Expression =>
3596               Actual := Get_Actual (Assoc);
3597            when Iir_Kind_Association_Element_By_Individual =>
3598               --  Directly create the whole value on the instance pool, as its
3599               --  life is longer than the statement.
3600               if Get_Kind (Inter) = Iir_Kind_Interface_Signal_Declaration then
3601                  Last_Individual := Create_Value_For_Type
3602                    (Out_Block, Get_Actual_Type (Assoc), Init_Value_Signal);
3603               else
3604                  Last_Individual := Create_Value_For_Type
3605                    (Out_Block, Get_Actual_Type (Assoc), Init_Value_Any);
3606               end if;
3607               Last_Individual :=
3608                 Unshare (Last_Individual, Instance_Pool);
3609               Elaboration.Create_Object (Subprg_Block, Inter);
3610               Subprg_Block.Objects (Get_Info (Inter).Slot) := Last_Individual;
3611               goto Continue;
3612            when others =>
3613               Error_Kind ("execute_association(1)", Assoc);
3614         end case;
3615
3616         --  Compute actual value.
3617         case Get_Kind (Inter) is
3618            when Iir_Kind_Interface_Constant_Declaration
3619              | Iir_Kind_Interface_File_Declaration =>
3620               Val := Execute_Expression (Out_Block, Actual);
3621               Implicit_Array_Conversion
3622                 (Out_Block, Val, Get_Type (Formal), Assoc);
3623               Check_Constraints (Out_Block, Val, Get_Type (Formal), Assoc);
3624            when Iir_Kind_Interface_Signal_Declaration =>
3625               Val := Execute_Name (Out_Block, Actual, True);
3626               Implicit_Array_Conversion
3627                 (Out_Block, Val, Get_Type (Formal), Assoc);
3628            when Iir_Kind_Interface_Variable_Declaration =>
3629               Mode := Get_Mode (Inter);
3630               if Mode = Iir_In_Mode then
3631                  --  FIXME: Ref ?
3632                  Val := Execute_Expression (Out_Block, Actual);
3633               else
3634                  Val := Execute_Name (Out_Block, Actual, False);
3635               end if;
3636
3637               --  FIXME: by value for scalars ?
3638
3639               --  Keep ref for back-copy
3640               if Mode /= Iir_In_Mode then
3641                  if Subprg_Block.Actuals_Ref = null then
3642                     declare
3643                        subtype Actuals_Ref_Type is
3644                          Value_Array (Iir_Index32 (Nbr_Assoc));
3645                        function To_Value_Array_Acc is new
3646                          Ada.Unchecked_Conversion (System.Address,
3647                                                    Value_Array_Acc);
3648                        function Alloc_Actuals_Ref is new
3649                          Alloc_On_Pool_Addr (Actuals_Ref_Type);
3650
3651                     begin
3652                        Subprg_Block.Actuals_Ref := To_Value_Array_Acc
3653                          (Alloc_Actuals_Ref
3654                             (Instance_Pool,
3655                              Actuals_Ref_Type'(Len => Iir_Index32 (Nbr_Assoc),
3656                                                V => (others => null))));
3657                     end;
3658                  end if;
3659                  Subprg_Block.Actuals_Ref.V (Assoc_Idx) :=
3660                    Unshare_Bounds (Val, Instance_Pool);
3661               end if;
3662
3663               if Mode = Iir_Out_Mode then
3664                  if Get_Formal_Conversion (Assoc) /= Null_Iir then
3665                     --  For an OUT variable using an out conversion, don't
3666                     --  associate with the actual, create a temporary value.
3667                     Val := Create_Value_For_Type
3668                       (Out_Block, Get_Type (Formal), Init_Value_Default);
3669                  elsif Get_Kind (Get_Type (Formal)) in
3670                    Iir_Kinds_Scalar_Type_And_Subtype_Definition
3671                  then
3672                     --  These are passed by value.  Must be reset.
3673                     Val := Create_Value_For_Type
3674                       (Out_Block, Get_Type (Formal), Init_Value_Default);
3675                  end if;
3676               else
3677                  if Get_Kind (Assoc) =
3678                    Iir_Kind_Association_Element_By_Expression
3679                  then
3680                     Conv := Get_Actual_Conversion (Assoc);
3681                     if Conv /= Null_Iir then
3682                        Val := Execute_Assoc_Conversion
3683                          (Out_Block, Conv, Val);
3684                     end if;
3685                  end if;
3686
3687                  --  FIXME: check constraints ?
3688               end if;
3689
3690               Implicit_Array_Conversion
3691                 (Out_Block, Val, Get_Type (Formal), Assoc);
3692
3693            when others =>
3694               Error_Kind ("execute_association(2)", Inter);
3695         end case;
3696
3697         if Get_Whole_Association_Flag (Assoc) then
3698            case Get_Kind (Inter) is
3699               when Iir_Kind_Interface_Constant_Declaration
3700                 | Iir_Kind_Interface_Variable_Declaration
3701                 | Iir_Kind_Interface_File_Declaration =>
3702                  --  FIXME: Arguments are passed by copy.
3703                  Elaboration.Create_Object (Subprg_Block, Inter);
3704                  Subprg_Block.Objects (Get_Info (Inter).Slot) :=
3705                    Unshare (Val, Instance_Pool);
3706               when Iir_Kind_Interface_Signal_Declaration =>
3707                  Elaboration.Create_Signal (Subprg_Block, Inter);
3708                  Subprg_Block.Objects (Get_Info (Inter).Slot) :=
3709                    Unshare_Bounds (Val, Instance_Pool);
3710               when others =>
3711                  Error_Kind ("execute_association", Inter);
3712            end case;
3713         else
3714            Associate_By_Reference
3715              (Subprg_Block, Formal, Last_Individual, Val);
3716         end if;
3717
3718         << Continue >> null;
3719         Next_Association_Interface (Assoc, Assoc_Inter);
3720         Assoc_Idx := Assoc_Idx + 1;
3721      end loop;
3722
3723      Release (Marker, Expr_Pool);
3724   end Execute_Association;
3725
3726   procedure Execute_Back_Association (Instance : Block_Instance_Acc)
3727   is
3728      Call : constant Iir := Get_Procedure_Call (Instance.Parent.Stmt);
3729      Imp : constant Iir := Get_Implementation (Call);
3730      Assoc : Iir;
3731      Assoc_Inter : Iir;
3732      Inter : Iir;
3733      Formal : Iir;
3734      Assoc_Idx : Iir_Index32;
3735   begin
3736      Assoc := Get_Parameter_Association_Chain (Call);
3737      Assoc_Inter := Get_Interface_Declaration_Chain (Imp);
3738      Assoc_Idx := 1;
3739      while Assoc /= Null_Iir loop
3740         if Get_Kind (Assoc) /= Iir_Kind_Association_Element_By_Individual then
3741            Inter := Get_Association_Interface (Assoc, Assoc_Inter);
3742            Formal := Get_Association_Formal (Assoc, Inter);
3743
3744            case Get_Kind (Inter) is
3745               when Iir_Kind_Interface_Variable_Declaration =>
3746                  if Get_Mode (Inter) /= Iir_In_Mode
3747                    and then Get_Kind (Get_Type (Inter)) /=
3748                    Iir_Kind_File_Type_Definition
3749                  then
3750                     --  For out/inout variable interface, the value must
3751                     --  be copied (FIXME: unless when passed by reference ?).
3752                     declare
3753                        Targ : constant Iir_Value_Literal_Acc :=
3754                          Instance.Actuals_Ref.V (Assoc_Idx);
3755                        Base : constant Iir_Value_Literal_Acc :=
3756                          Instance.Objects (Get_Info (Inter).Slot);
3757                        Val : Iir_Value_Literal_Acc;
3758                        Conv : Iir;
3759                        Is_Sig : Boolean;
3760                        Expr_Mark : Mark_Type;
3761                     begin
3762                        Mark (Expr_Mark, Expr_Pool);
3763
3764                        --  Extract for individual association.
3765                        Execute_Name_With_Base
3766                          (Instance, Formal, Base, Val, Is_Sig);
3767                        Conv := Get_Formal_Conversion (Assoc);
3768                        if Conv /= Null_Iir then
3769                           Val := Execute_Assoc_Conversion
3770                             (Instance, Conv, Val);
3771                           --  FIXME: free val ?
3772                        end if;
3773                        Store (Targ, Val);
3774
3775                        Release (Expr_Mark, Expr_Pool);
3776                     end;
3777                  end if;
3778               when Iir_Kind_Interface_File_Declaration =>
3779                  null;
3780               when Iir_Kind_Interface_Signal_Declaration
3781                 | Iir_Kind_Interface_Constant_Declaration =>
3782                  null;
3783               when others =>
3784                  Error_Kind ("execute_back_association", Inter);
3785            end case;
3786         end if;
3787         Next_Association_Interface (Assoc, Assoc_Inter);
3788         Assoc_Idx := Assoc_Idx + 1;
3789      end loop;
3790   end Execute_Back_Association;
3791
3792   function Execute_Foreign_Function_Call
3793     (Block: Block_Instance_Acc; Expr : Iir; Imp : Iir)
3794      return Iir_Value_Literal_Acc
3795   is
3796      Res : Iir_Value_Literal_Acc;
3797   begin
3798      case Get_Identifier (Imp) is
3799         when Std_Names.Name_Get_Resolution_Limit =>
3800            Res := Create_I64_Value (1);
3801         when Std_Names.Name_Textio_Read_Real =>
3802            Res := Create_F64_Value
3803              (File_Operation.Textio_Read_Real (Block.Objects (1)));
3804         when others =>
3805            Error_Msg_Exec ("unsupported foreign function call", Expr);
3806      end case;
3807      return Res;
3808   end Execute_Foreign_Function_Call;
3809
3810   -- BLOCK is the block instance in which the function call appears.
3811   function Execute_Function_Call
3812     (Block: Block_Instance_Acc; Expr: Iir; Imp : Iir)
3813      return Iir_Value_Literal_Acc
3814   is
3815      Inter_Chain : constant Iir := Get_Interface_Declaration_Chain (Imp);
3816      Subprg_Block: Block_Instance_Acc;
3817      Prot_Block : Block_Instance_Acc;
3818      Assoc_Chain: Iir;
3819      Res : Iir_Value_Literal_Acc;
3820   begin
3821      Mark (Block.Marker, Instance_Pool.all);
3822
3823      case Get_Kind (Expr) is
3824         when Iir_Kind_Function_Call =>
3825            Prot_Block := Get_Protected_Object_Instance (Block, Expr);
3826            Subprg_Block :=
3827              Create_Subprogram_Instance (Block, Prot_Block, Imp);
3828            Assoc_Chain := Get_Parameter_Association_Chain (Expr);
3829            Execute_Association
3830              (Block, Subprg_Block, Inter_Chain, Assoc_Chain);
3831            --  No out/inout interface for functions.
3832            pragma Assert (Subprg_Block.Actuals_Ref = null);
3833         when Iir_Kinds_Dyadic_Operator =>
3834            Subprg_Block := Create_Subprogram_Instance (Block, null, Imp);
3835            Execute_Dyadic_Association
3836              (Block, Subprg_Block, Expr, Inter_Chain);
3837         when Iir_Kinds_Monadic_Operator =>
3838            Subprg_Block := Create_Subprogram_Instance (Block, null, Imp);
3839            Execute_Monadic_Association
3840              (Block, Subprg_Block, Expr, Inter_Chain);
3841         when others =>
3842            Error_Kind ("execute_subprogram_call_init", Expr);
3843      end case;
3844
3845      if Get_Foreign_Flag (Imp) then
3846         Res := Execute_Foreign_Function_Call (Subprg_Block, Expr, Imp);
3847      else
3848         Res := Execute_Function_Body (Subprg_Block);
3849      end if;
3850
3851      --  Unfortunately, we don't know where the result has been allocated,
3852      --  so copy it before releasing the instance pool.
3853      Res := Unshare (Res, Expr_Pool'Access);
3854
3855      Release (Block.Marker, Instance_Pool.all);
3856
3857      return Res;
3858   end Execute_Function_Call;
3859
3860   --  Slide an array VALUE using bounds from REF_VALUE.  Do not modify
3861   --  VALUE if not an array.
3862   procedure Implicit_Array_Conversion (Value : in out Iir_Value_Literal_Acc;
3863                                        Ref_Value : Iir_Value_Literal_Acc;
3864                                        Expr : Iir)
3865   is
3866      Res : Iir_Value_Literal_Acc;
3867   begin
3868      if Value.Kind /= Iir_Value_Array then
3869         return;
3870      end if;
3871      Res := Create_Array_Value (Value.Bounds.Nbr_Dims);
3872      Res.Val_Array := Value.Val_Array;
3873      for I in Value.Bounds.D'Range loop
3874         if Value.Bounds.D (I).Length /= Ref_Value.Bounds.D (I).Length then
3875            Error_Msg_Constraint (Expr);
3876            return;
3877         end if;
3878         Res.Bounds.D (I) := Ref_Value.Bounds.D (I);
3879      end loop;
3880      Value := Res;
3881   end Implicit_Array_Conversion;
3882
3883   procedure Implicit_Array_Conversion (Instance : Block_Instance_Acc;
3884                                        Value : in out Iir_Value_Literal_Acc;
3885                                        Ref_Type : Iir;
3886                                        Expr : Iir)
3887   is
3888      Ref_Value : Iir_Value_Literal_Acc;
3889   begin
3890      --  Do array conversion only if REF_TYPE is a constrained array type
3891      --  definition.
3892      if Value.Kind /= Iir_Value_Array then
3893         return;
3894      end if;
3895      if Get_Constraint_State (Ref_Type) /= Fully_Constrained then
3896         return;
3897      end if;
3898      Ref_Value := Create_Array_Bounds_From_Type (Instance, Ref_Type, True);
3899      for I in Value.Bounds.D'Range loop
3900         if Value.Bounds.D (I).Length /= Ref_Value.Bounds.D (I).Length then
3901            Error_Msg_Constraint (Expr);
3902            return;
3903         end if;
3904      end loop;
3905      Ref_Value.Val_Array.V := Value.Val_Array.V;
3906      Value := Ref_Value;
3907   end Implicit_Array_Conversion;
3908
3909   procedure Check_Range_Constraints (Instance : Block_Instance_Acc;
3910                                      Rng : Iir_Value_Literal_Acc;
3911                                      Rng_Type : Iir;
3912                                      Loc : Iir) is
3913   begin
3914      if not Is_Null_Range (Rng) then
3915         Check_Constraints (Instance, Rng.Left, Get_Type (Rng_Type), Loc);
3916         Check_Constraints (Instance, Rng.Right, Get_Type (Rng_Type), Loc);
3917      end if;
3918   end Check_Range_Constraints;
3919
3920   procedure Check_Array_Constraints (Instance: Block_Instance_Acc;
3921                                      Value: Iir_Value_Literal_Acc;
3922                                      Def: Iir;
3923                                      Expr: Iir)
3924   is
3925      Index_List : Iir_Flist;
3926      Element_Subtype : Iir;
3927      New_Bounds : Iir_Value_Literal_Acc;
3928   begin
3929      --  Nothing to check for unconstrained arrays.
3930      if not Get_Index_Constraint_Flag (Def) then
3931         return;
3932      end if;
3933
3934      Index_List := Get_Index_Subtype_List (Def);
3935      for I in Value.Bounds.D'Range loop
3936         New_Bounds := Execute_Bounds
3937           (Instance, Get_Nth_Element (Index_List, Natural (I - 1)));
3938         if not Is_Equal (Value.Bounds.D (I), New_Bounds) then
3939            Error_Msg_Constraint (Expr);
3940            return;
3941         end if;
3942      end loop;
3943
3944      if Boolean'(False) then
3945         Index_List := Get_Index_List (Def);
3946         Element_Subtype := Get_Element_Subtype (Def);
3947         for I in Value.Val_Array.V'Range loop
3948            Check_Constraints
3949              (Instance, Value.Val_Array.V (I), Element_Subtype, Expr);
3950         end loop;
3951      end if;
3952   end Check_Array_Constraints;
3953
3954   --  Check DEST and SRC are array compatible.
3955   procedure Check_Array_Match (Instance: Block_Instance_Acc;
3956                                Dest: Iir_Value_Literal_Acc;
3957                                Src : Iir_Value_Literal_Acc;
3958                                Expr: Iir)
3959   is
3960      pragma Unreferenced (Instance);
3961   begin
3962      for I in Dest.Bounds.D'Range loop
3963         if Dest.Bounds.D (I).Length /= Src.Bounds.D (I).Length then
3964            Error_Msg_Constraint (Expr);
3965            exit;
3966         end if;
3967      end loop;
3968   end Check_Array_Match;
3969   pragma Unreferenced (Check_Array_Match);
3970
3971   procedure Check_Constraints (Instance: Block_Instance_Acc;
3972                                Value: Iir_Value_Literal_Acc;
3973                                Def: Iir;
3974                                Expr: Iir)
3975   is
3976      High, Low: Iir_Value_Literal_Acc;
3977      Bound : Iir_Value_Literal_Acc;
3978   begin
3979      case Get_Kind (Def) is
3980         when Iir_Kind_Integer_Subtype_Definition
3981           | Iir_Kind_Floating_Subtype_Definition
3982           | Iir_Kind_Enumeration_Subtype_Definition
3983           | Iir_Kind_Physical_Subtype_Definition
3984           | Iir_Kind_Enumeration_Type_Definition =>
3985            Bound := Execute_Bounds (Instance, Def);
3986            if Bound.Dir = Dir_To then
3987               High := Bound.Right;
3988               Low := Bound.Left;
3989            else
3990               High := Bound.Left;
3991               Low := Bound.Right;
3992            end if;
3993            case Iir_Value_Scalars (Value.Kind) is
3994               when Iir_Value_I64 =>
3995                  if Value.I64 in Low.I64 .. High.I64 then
3996                     return;
3997                  end if;
3998               when Iir_Value_E8 =>
3999                  if Value.E8 in Low.E8 .. High.E8 then
4000                     return;
4001                  end if;
4002               when Iir_Value_E32 =>
4003                  if Value.E32 in Low.E32 .. High.E32 then
4004                     return;
4005                  end if;
4006               when Iir_Value_F64 =>
4007                  if Value.F64 in Low.F64 .. High.F64 then
4008                     return;
4009                  end if;
4010               when Iir_Value_B1 =>
4011                  if Value.B1 in Low.B1 .. High.B1 then
4012                     return;
4013                  end if;
4014            end case;
4015         when Iir_Kind_Array_Subtype_Definition
4016           | Iir_Kind_Array_Type_Definition =>
4017            Check_Array_Constraints (Instance, Value, Def, Expr);
4018            return;
4019         when Iir_Kind_Record_Type_Definition
4020           | Iir_Kind_Record_Subtype_Definition =>
4021            declare
4022               List : constant Iir_Flist :=
4023                 Get_Elements_Declaration_List (Get_Base_Type (Def));
4024               El : Iir_Element_Declaration;
4025            begin
4026               for I in Flist_First .. Flist_Last (List) loop
4027                  El := Get_Nth_Element (List, I);
4028                  Check_Constraints
4029                    (Instance,
4030                     Value.Val_Record.V (Get_Element_Position (El) + 1),
4031                     Get_Type (El),
4032                     Expr);
4033               end loop;
4034            end;
4035            return;
4036         when Iir_Kind_Integer_Type_Definition =>
4037            return;
4038         when Iir_Kind_Floating_Type_Definition =>
4039            return;
4040         when Iir_Kind_Physical_Type_Definition =>
4041            return;
4042         when Iir_Kind_Access_Type_Definition
4043           | Iir_Kind_Access_Subtype_Definition =>
4044            return;
4045         when Iir_Kind_File_Type_Definition =>
4046            return;
4047         when others =>
4048            Error_Kind ("check_constraints", Def);
4049      end case;
4050      Error_Msg_Constraint (Expr);
4051   end Check_Constraints;
4052
4053   function Execute_Resolution_Function
4054     (Block: Block_Instance_Acc; Imp : Iir; Arr : Iir_Value_Literal_Acc)
4055      return Iir_Value_Literal_Acc
4056   is
4057      Inter : Iir;
4058      Instance : Block_Instance_Acc;
4059   begin
4060      -- Create a frame for this function.
4061      Instance := Create_Subprogram_Instance (Block, null, Imp);
4062
4063      Inter := Get_Interface_Declaration_Chain (Imp);
4064      Elaboration.Create_Object (Instance, Inter);
4065      Instance.Objects (Get_Info (Inter).Slot) := Arr;
4066
4067      return Execute_Function_Body (Instance);
4068   end Execute_Resolution_Function;
4069
4070   procedure Execute_Signal_Assignment (Instance: Block_Instance_Acc;
4071                                        Stmt: Iir_Signal_Assignment_Statement;
4072                                        Wf : Iir)
4073   is
4074      Nbr_We : constant Natural := Get_Chain_Length (Wf);
4075
4076      Transactions : Transaction_Type (Nbr_We);
4077
4078      We: Iir_Waveform_Element;
4079      Res: Iir_Value_Literal_Acc;
4080      Rdest: Iir_Value_Literal_Acc;
4081      Targ_Type : Iir;
4082      Marker : Mark_Type;
4083   begin
4084      Mark (Marker, Expr_Pool);
4085
4086      Rdest := Execute_Name (Instance, Get_Target (Stmt), True);
4087      Targ_Type := Get_Type (Get_Target (Stmt));
4088
4089      --  Disconnection statement.
4090      if Wf = Null_Iir then
4091         Disconnect_Signal (Rdest);
4092         Release (Marker, Expr_Pool);
4093         return;
4094      elsif Get_Kind (Wf) = Iir_Kind_Unaffected_Waveform then
4095         return;
4096      end if;
4097
4098      Transactions.Stmt := Stmt;
4099
4100      -- LRM93 8.4.1
4101      -- Evaluation of a waveform consists of the evaluation of each waveform
4102      -- elements in the waveform.
4103      We := Wf;
4104      for I in Transactions.Els'Range loop
4105         declare
4106            Trans : Transaction_El_Type renames Transactions.Els (I);
4107         begin
4108            if Get_Time (We) /= Null_Iir then
4109               Res := Execute_Expression (Instance, Get_Time (We));
4110               -- LRM93 8.4.1
4111               -- It is an error if the time expression in a waveform element
4112               -- evaluates to a negative value.
4113               if Res.I64 < 0 then
4114                  Error_Msg_Exec ("time value is negative", Get_Time (We));
4115               end if;
4116               Trans.After := Std_Time (Res.I64);
4117            else
4118               -- LRM93 8.4.1
4119               -- If the after clause of a waveform element is not present,
4120               -- then an implicit "after 0 ns" is assumed.
4121               Trans.After := 0;
4122            end if;
4123
4124            -- LRM93 8.4.1
4125            -- It is an error if the sequence of new transactions is not in
4126            -- ascending order with respect to time.
4127            if I > 1
4128              and then Trans.After <= Transactions.Els (I - 1).After
4129            then
4130               Error_Msg_Exec
4131                 ("sequence not in ascending order with respect to time", We);
4132            end if;
4133
4134            if Get_Kind (Get_We_Value (We)) = Iir_Kind_Null_Literal then
4135               -- null transaction.
4136               Trans.Value := null;
4137            else
4138               -- LRM93 8.4.1
4139               -- For the first form of waveform element, the value component
4140               -- of the transaction is determined by the value expression in
4141               -- the waveform element.
4142               Trans.Value := Execute_Expression_With_Type
4143                 (Instance, Get_We_Value (We), Targ_Type);
4144            end if;
4145         end;
4146         We := Get_Chain (We);
4147      end loop;
4148      pragma Assert (We = Null_Iir);
4149
4150      case Get_Delay_Mechanism (Stmt) is
4151         when Iir_Transport_Delay =>
4152            Transactions.Reject := 0;
4153         when Iir_Inertial_Delay =>
4154            -- LRM93 8.4
4155            -- or, in the case that a pulse rejection limit is specified,
4156            -- a pulse whose duration is shorter than that limit will not
4157            -- be transmitted.
4158            -- Every inertially delayed signal assignment has a pulse
4159            -- rejection limit.
4160            if Get_Reject_Time_Expression (Stmt) /= Null_Iir then
4161               -- LRM93 8.4
4162               -- If the delay mechanism specifies inertial delay, and if the
4163               -- reserved word reject followed by a time expression is
4164               -- present, then the time expression specifies the pulse
4165               -- rejection limit.
4166               Res := Execute_Expression
4167                 (Instance, Get_Reject_Time_Expression (Stmt));
4168               -- LRM93 8.4
4169               -- It is an error if the pulse rejection limit for any
4170               -- inertially delayed signal assignement statement is either
4171               -- negative ...
4172               if Res.I64 < 0 then
4173                  Error_Msg_Exec ("reject time negative", Stmt);
4174               end if;
4175               -- LRM93 8.4
4176               -- ... or greather than the time expression associated with
4177               -- the first waveform element.
4178               Transactions.Reject := Std_Time (Res.I64);
4179               if Transactions.Reject > Transactions.Els (1).After then
4180                  Error_Msg_Exec
4181                    ("reject time greather than time expression", Stmt);
4182               end if;
4183            else
4184               -- LRM93 8.4
4185               -- In all other cases, the pulse rejection limit is the time
4186               -- expression associated ith the first waveform element.
4187               Transactions.Reject := Transactions.Els (1).After;
4188            end if;
4189      end case;
4190
4191      --  FIXME: slice Transactions to remove transactions after end of time.
4192      Assign_Value_To_Signal (Instance, Rdest, Transactions);
4193
4194      Release (Marker, Expr_Pool);
4195   end Execute_Signal_Assignment;
4196
4197   -- Display a message when an assertion has failed.
4198   -- REPORT is the value (string) to display, or null to use default message.
4199   -- SEVERITY is the severity or null to use default (error).
4200   -- STMT is used to display location.
4201   procedure Execute_Failed_Assertion (Msg : String;
4202                                       Report : String;
4203                                       Severity : Natural;
4204                                       Stmt: Iir) is
4205   begin
4206      -- LRM93 8.2
4207      -- The error message consists of at least:
4208
4209      -- 4: name of the design unit containing the assertion.
4210      Put (Disp_Location (Stmt));
4211
4212      Put (":@");
4213      Grt.Astdio.Vhdl.Put_Time (Grt.Stdio.stdout, Current_Time);
4214
4215      -- 1: an indication that this message is from an assertion.
4216      Put (":(");
4217      Put (Msg);
4218      Put (' ');
4219
4220      -- 2: the value of the severity level.
4221      case Severity is
4222         when 0 =>
4223            Put ("note");
4224         when 1 =>
4225            Put ("warning");
4226         when 2 =>
4227            Put ("error");
4228         when 3 =>
4229            Put ("failure");
4230         when others =>
4231            Error_Internal (Null_Iir, "execute_failed_assertion");
4232      end case;
4233      Put ("): ");
4234
4235      -- 3: the value of the message string.
4236      Put_Line (Report);
4237
4238      -- Stop execution if the severity is too high.
4239      if Severity >= Grt.Options.Severity_Level then
4240         Debug (Reason_Assert);
4241         Grt.Errors.Fatal_Error;
4242      end if;
4243   end Execute_Failed_Assertion;
4244
4245   procedure Execute_Failed_Assertion (Instance: Block_Instance_Acc;
4246                                       Label : String;
4247                                       Stmt : Iir;
4248                                       Default_Msg : String;
4249                                       Default_Severity : Natural)
4250   is
4251      Expr: Iir;
4252      Report, Severity_Lit: Iir_Value_Literal_Acc;
4253      Severity : Natural;
4254      Marker : Mark_Type;
4255   begin
4256      Mark (Marker, Expr_Pool);
4257      Expr := Get_Report_Expression (Stmt);
4258      if Expr /= Null_Iir then
4259         Report := Execute_Expression (Instance, Expr);
4260      else
4261         Report := null;
4262      end if;
4263      Expr := Get_Severity_Expression (Stmt);
4264      if Expr /= Null_Iir then
4265         Severity_Lit := Execute_Expression (Instance, Expr);
4266         Severity := Natural'Val (Severity_Lit.E8);
4267      else
4268         Severity := Default_Severity;
4269      end if;
4270      if Report /= null then
4271         declare
4272            Msg : String (1 .. Natural (Report.Val_Array.Len));
4273         begin
4274            for I in Report.Val_Array.V'Range loop
4275               Msg (Positive (I)) :=
4276                 Character'Val (Report.Val_Array.V (I).E8);
4277            end loop;
4278            Execute_Failed_Assertion (Label, Msg, Severity, Stmt);
4279         end;
4280      else
4281         Execute_Failed_Assertion (Label, Default_Msg, Severity, Stmt);
4282      end if;
4283      Release (Marker, Expr_Pool);
4284   end Execute_Failed_Assertion;
4285
4286   function Is_In_Choice (Instance : Block_Instance_Acc;
4287                          Choice : Iir;
4288                          Expr : Iir_Value_Literal_Acc)
4289                         return Boolean
4290   is
4291      Res : Boolean;
4292   begin
4293      case Get_Kind (Choice) is
4294         when Iir_Kind_Choice_By_Others =>
4295            return True;
4296         when Iir_Kind_Choice_By_Expression =>
4297            declare
4298               Expr1: Iir_Value_Literal_Acc;
4299            begin
4300               Expr1 := Execute_Expression
4301                 (Instance, Get_Choice_Expression (Choice));
4302               Res := Is_Equal (Expr, Expr1);
4303               return Res;
4304            end;
4305         when Iir_Kind_Choice_By_Range =>
4306            declare
4307               A_Range : Iir_Value_Literal_Acc;
4308            begin
4309               A_Range := Execute_Bounds
4310                 (Instance, Get_Choice_Range (Choice));
4311               Res := Is_In_Range (Expr, A_Range);
4312            end;
4313            return Res;
4314         when others =>
4315            Error_Kind ("is_in_choice", Choice);
4316      end case;
4317   end Is_In_Choice;
4318
4319   function Execute_Choice (Instance : Block_Instance_Acc;
4320                            Expr : Iir;
4321                            First_Assoc : Iir) return Iir
4322   is
4323      Value: Iir_Value_Literal_Acc;
4324      Assoc: Iir;
4325      Assoc_Res : Iir;
4326      Marker : Mark_Type;
4327   begin
4328      Mark (Marker, Expr_Pool);
4329      Assoc := First_Assoc;
4330
4331      Value := Execute_Expression (Instance, Expr);
4332      if Get_Type_Staticness (Get_Type (Expr)) /= Locally
4333        and then Get_Kind (Assoc) = Iir_Kind_Choice_By_Expression
4334      then
4335         --  Choice is not locally constrained, check length.
4336         declare
4337            Choice_Type : constant Iir :=
4338              Get_Type (Get_Choice_Expression (Assoc));
4339            Choice_Len : Int64;
4340         begin
4341            Choice_Len := Vhdl.Evaluation.Eval_Discrete_Type_Length
4342              (Get_String_Type_Bound_Type (Choice_Type));
4343            if Choice_Len /= Int64 (Value.Bounds.D (1).Length) then
4344               Error_Msg_Constraint (Expr);
4345            end if;
4346         end;
4347      end if;
4348
4349      while Assoc /= Null_Iir loop
4350         if not Get_Same_Alternative_Flag (Assoc) then
4351            Assoc_Res := Assoc;
4352         end if;
4353
4354         if Is_In_Choice (Instance, Assoc, Value) then
4355            Release (Marker, Expr_Pool);
4356            return Assoc_Res;
4357         end if;
4358
4359         Assoc := Get_Chain (Assoc);
4360      end loop;
4361      --  FIXME: infinite loop???
4362      Error_Msg_Exec ("no choice for expression", Expr);
4363      raise Internal_Error;
4364   end Execute_Choice;
4365
4366   --  Return TRUE iff VAL is in the range defined by BOUNDS.
4367   function Is_In_Range (Val : Iir_Value_Literal_Acc;
4368                         Bounds : Iir_Value_Literal_Acc)
4369     return Boolean
4370   is
4371      Max, Min : Iir_Value_Literal_Acc;
4372   begin
4373      case Bounds.Dir is
4374         when Dir_To =>
4375            Min := Bounds.Left;
4376            Max := Bounds.Right;
4377         when Dir_Downto =>
4378            Min := Bounds.Right;
4379            Max := Bounds.Left;
4380      end case;
4381
4382      case Iir_Value_Discrete (Val.Kind) is
4383         when Iir_Value_E8 =>
4384            return Val.E8 >= Min.E8 and Val.E8 <= Max.E8;
4385         when Iir_Value_E32 =>
4386            return Val.E32 >= Min.E32 and Val.E32 <= Max.E32;
4387         when Iir_Value_B1 =>
4388            return Val.B1 >= Min.B1 and Val.B1 <= Max.B1;
4389         when Iir_Value_I64 =>
4390            return Val.I64 >= Min.I64 and Val.I64 <= Max.I64;
4391      end case;
4392   end Is_In_Range;
4393
4394   --  Increment or decrement VAL according to BOUNDS.DIR.
4395   --  FIXME: use increment ?
4396   procedure Update_Loop_Index (Val : Iir_Value_Literal_Acc;
4397                                Bounds : Iir_Value_Literal_Acc)
4398   is
4399   begin
4400      case Iir_Value_Discrete (Val.Kind) is
4401         when Iir_Value_E8 =>
4402            case Bounds.Dir is
4403               when Dir_To =>
4404                  Val.E8 := Val.E8 + 1;
4405               when Dir_Downto =>
4406                  Val.E8 := Val.E8 - 1;
4407            end case;
4408         when Iir_Value_E32 =>
4409            case Bounds.Dir is
4410               when Dir_To =>
4411                  Val.E32 := Val.E32 + 1;
4412               when Dir_Downto =>
4413                  Val.E32 := Val.E32 - 1;
4414            end case;
4415         when Iir_Value_B1 =>
4416            case Bounds.Dir is
4417               when Dir_To =>
4418                  Val.B1 := True;
4419               when Dir_Downto =>
4420                  Val.B1 := False;
4421            end case;
4422         when Iir_Value_I64 =>
4423            case Bounds.Dir is
4424               when Dir_To =>
4425                  Val.I64 := Val.I64 + 1;
4426               when Dir_Downto =>
4427                  Val.I64 := Val.I64 - 1;
4428            end case;
4429      end case;
4430   end Update_Loop_Index;
4431
4432   procedure Finalize_For_Loop_Statement (Instance : Block_Instance_Acc;
4433                                          Stmt : Iir)
4434   is
4435   begin
4436      Destroy_Iterator_Declaration
4437        (Instance, Get_Parameter_Specification (Stmt));
4438   end Finalize_For_Loop_Statement;
4439
4440   procedure Finalize_Loop_Statement (Instance : Block_Instance_Acc;
4441                                      Stmt : Iir)
4442   is
4443   begin
4444      if Get_Kind (Stmt) = Iir_Kind_For_Loop_Statement then
4445         Finalize_For_Loop_Statement (Instance, Stmt);
4446      end if;
4447   end Finalize_Loop_Statement;
4448
4449   procedure Execute_For_Loop_Statement (Proc : Process_State_Acc)
4450   is
4451      Instance : constant Block_Instance_Acc := Proc.Instance;
4452      Stmt : constant Iir_For_Loop_Statement := Instance.Stmt;
4453      Iterator : constant Iir := Get_Parameter_Specification (Stmt);
4454      Bounds : Iir_Value_Literal_Acc;
4455      Index : Iir_Value_Literal_Acc;
4456      Stmt_Chain : Iir;
4457      Is_Nul : Boolean;
4458      Marker : Mark_Type;
4459   begin
4460      --  Elaborate the iterator (and its type).
4461      Elaborate_Declaration (Instance, Iterator);
4462
4463      -- Extract bounds.
4464      Mark (Marker, Expr_Pool);
4465      Bounds := Execute_Bounds (Instance, Get_Type (Iterator));
4466      Index := Instance.Objects (Get_Info (Iterator).Slot);
4467      Store (Index, Bounds.Left);
4468      Is_Nul := Is_Null_Range (Bounds);
4469      Release (Marker, Expr_Pool);
4470
4471      if Is_Nul then
4472         -- Loop is complete.
4473         Finalize_For_Loop_Statement (Instance, Stmt);
4474         Update_Next_Statement (Proc);
4475      else
4476         Stmt_Chain := Get_Sequential_Statement_Chain (Stmt);
4477         if Stmt_Chain = Null_Iir then
4478            --  Nothing to do for an empty loop.
4479            Finalize_For_Loop_Statement (Instance, Stmt);
4480            Update_Next_Statement (Proc);
4481         else
4482            Instance.Stmt := Stmt_Chain;
4483         end if;
4484      end if;
4485   end Execute_For_Loop_Statement;
4486
4487   --  This function is called when there is no more statements to execute
4488   --  in the statement list of a for_loop.  Returns FALSE in case of end of
4489   --  loop.
4490   function Finish_For_Loop_Statement (Instance : Block_Instance_Acc)
4491                                      return Boolean
4492   is
4493      Iterator : constant Iir := Get_Parameter_Specification (Instance.Stmt);
4494      Bounds : Iir_Value_Literal_Acc;
4495      Index : Iir_Value_Literal_Acc;
4496      Marker : Mark_Type;
4497   begin
4498      --  FIXME: avoid allocation.
4499      Mark (Marker, Expr_Pool);
4500      Bounds := Execute_Bounds (Instance, Get_Type (Iterator));
4501      Index := Instance.Objects (Get_Info (Iterator).Slot);
4502
4503      if Is_Equal (Index, Bounds.Right) then
4504         -- Loop is complete.
4505         Release (Marker, Expr_Pool);
4506         Finalize_For_Loop_Statement (Instance, Instance.Stmt);
4507         return False;
4508      else
4509         -- Update the loop index.
4510         Update_Loop_Index (Index, Bounds);
4511
4512         Release (Marker, Expr_Pool);
4513
4514         -- start the loop again.
4515         Instance.Stmt := Get_Sequential_Statement_Chain (Instance.Stmt);
4516         return True;
4517      end if;
4518   end Finish_For_Loop_Statement;
4519
4520   --  Evaluate boolean condition COND.  If COND is Null_Iir, returns true.
4521   function Execute_Condition (Instance : Block_Instance_Acc;
4522                               Cond : Iir) return Boolean
4523   is
4524      V : Iir_Value_Literal_Acc;
4525      Res : Boolean;
4526      Marker : Mark_Type;
4527   begin
4528      if Cond = Null_Iir then
4529         return True;
4530      end if;
4531
4532      Mark (Marker, Expr_Pool);
4533      V := Execute_Expression (Instance, Cond);
4534      Res := V.B1 = True;
4535      Release (Marker, Expr_Pool);
4536      return Res;
4537   end Execute_Condition;
4538
4539   --  Start a while loop statement, or return FALSE if the loop is not
4540   --  executed.
4541   procedure Execute_While_Loop_Statement (Proc : Process_State_Acc)
4542   is
4543      Instance: constant Block_Instance_Acc := Proc.Instance;
4544      Stmt : constant Iir := Instance.Stmt;
4545      Cond : Boolean;
4546   begin
4547      Cond := Execute_Condition (Instance, Get_Condition (Stmt));
4548      if Cond then
4549         Init_Sequential_Statements (Proc, Stmt);
4550      else
4551         Update_Next_Statement (Proc);
4552      end if;
4553   end Execute_While_Loop_Statement;
4554
4555   --  This function is called when there is no more statements to execute
4556   --  in the statement list of a while loop.  Returns FALSE iff loop is
4557   --  completed.
4558   function Finish_While_Loop_Statement (Instance : Block_Instance_Acc)
4559                                        return Boolean
4560   is
4561      Cond : Boolean;
4562   begin
4563      Cond := Execute_Condition (Instance, Get_Condition (Instance.Stmt));
4564
4565      if Cond then
4566         -- start the loop again.
4567         Instance.Stmt := Get_Sequential_Statement_Chain (Instance.Stmt);
4568         return True;
4569      else
4570         -- Loop is complete.
4571         return False;
4572      end if;
4573   end Finish_While_Loop_Statement;
4574
4575   --  Return TRUE if the loop must be executed again
4576   function Finish_Loop_Statement (Instance : Block_Instance_Acc; Stmt : Iir)
4577                                  return Boolean is
4578   begin
4579      Instance.Stmt := Stmt;
4580      case Get_Kind (Stmt) is
4581         when Iir_Kind_While_Loop_Statement =>
4582            return Finish_While_Loop_Statement (Instance);
4583         when Iir_Kind_For_Loop_Statement =>
4584            return Finish_For_Loop_Statement (Instance);
4585         when others =>
4586            Error_Kind ("finish_loop_statement", Stmt);
4587      end case;
4588   end Finish_Loop_Statement;
4589
4590   --  Return FALSE if the next statement should be executed (possibly
4591   --  updated).
4592   procedure Execute_Exit_Next_Statement (Proc : Process_State_Acc;
4593                                          Is_Exit : Boolean)
4594   is
4595      Instance : constant Block_Instance_Acc := Proc.Instance;
4596      Stmt : constant Iir := Instance.Stmt;
4597      Label : constant Iir := Get_Named_Entity (Get_Loop_Label (Stmt));
4598      Cond : Boolean;
4599      Parent : Iir;
4600   begin
4601      Cond := Execute_Condition (Instance, Get_Condition (Stmt));
4602      if not Cond then
4603         Update_Next_Statement (Proc);
4604         return;
4605      end if;
4606
4607      Parent := Stmt;
4608      loop
4609         Parent := Get_Parent (Parent);
4610         case Get_Kind (Parent) is
4611            when Iir_Kind_For_Loop_Statement
4612              | Iir_Kind_While_Loop_Statement =>
4613               if Label = Null_Iir or else Label = Parent then
4614                  --  Target is this statement.
4615                  if Is_Exit then
4616                     Finalize_Loop_Statement (Instance, Parent);
4617                     Instance.Stmt := Parent;
4618                     Update_Next_Statement (Proc);
4619                  elsif not Finish_Loop_Statement (Instance, Parent) then
4620                     Update_Next_Statement (Proc);
4621                  else
4622                     Init_Sequential_Statements (Proc, Parent);
4623                  end if;
4624                  return;
4625               else
4626                  Finalize_Loop_Statement (Instance, Parent);
4627               end if;
4628            when others =>
4629               null;
4630         end case;
4631      end loop;
4632   end Execute_Exit_Next_Statement;
4633
4634   procedure Execute_Case_Statement (Proc : Process_State_Acc)
4635   is
4636      Instance : constant Block_Instance_Acc := Proc.Instance;
4637      Stmt : constant Iir := Instance.Stmt;
4638      Assoc: Iir;
4639      Stmt_Chain : Iir;
4640   begin
4641      Assoc := Execute_Choice (Instance, Get_Expression (Stmt),
4642                               Get_Case_Statement_Alternative_Chain (Stmt));
4643      Stmt_Chain := Get_Associated_Chain (Assoc);
4644      if Stmt_Chain = Null_Iir then
4645         Update_Next_Statement (Proc);
4646      else
4647         Instance.Stmt := Stmt_Chain;
4648      end if;
4649   end Execute_Case_Statement;
4650
4651   procedure Execute_Call_Statement (Proc : Process_State_Acc)
4652   is
4653      Instance : constant Block_Instance_Acc := Proc.Instance;
4654      Stmt : constant Iir := Instance.Stmt;
4655      Call : constant Iir := Get_Procedure_Call (Stmt);
4656      Imp  : constant Iir := Get_Implementation (Call);
4657      Subprg_Instance : Block_Instance_Acc;
4658      Prot_Block : Block_Instance_Acc;
4659      Assoc_Chain: Iir;
4660      Inter_Chain : Iir;
4661   begin
4662      if Get_Implicit_Definition (Imp) in Iir_Predefined_Implicit then
4663         Execute_Implicit_Procedure (Instance, Call);
4664         Update_Next_Statement (Proc);
4665      elsif Get_Foreign_Flag (Imp) then
4666         Execute_Foreign_Procedure (Instance, Call);
4667         Update_Next_Statement (Proc);
4668      else
4669         Mark (Instance.Marker, Instance_Pool.all);
4670         Prot_Block := Get_Protected_Object_Instance (Instance, Call);
4671         Subprg_Instance :=
4672           Create_Subprogram_Instance (Instance, Prot_Block, Imp);
4673         Assoc_Chain := Get_Parameter_Association_Chain (Call);
4674         Inter_Chain := Get_Interface_Declaration_Chain (Imp);
4675         Execute_Association
4676           (Instance, Subprg_Instance, Inter_Chain, Assoc_Chain);
4677
4678         Current_Process.Instance := Subprg_Instance;
4679         Elaborate_Declarative_Part
4680           (Subprg_Instance, Get_Declaration_Chain (Subprg_Instance.Bod));
4681
4682         Init_Sequential_Statements (Proc, Subprg_Instance.Bod);
4683      end if;
4684   end Execute_Call_Statement;
4685
4686   procedure Finish_Procedure_Frame (Proc : Process_State_Acc)
4687   is
4688      Old_Instance : constant Block_Instance_Acc := Proc.Instance;
4689   begin
4690      Execute_Back_Association (Old_Instance);
4691      Proc.Instance := Old_Instance.Parent;
4692      Execute_Subprogram_Call_Final (Old_Instance);
4693      Release (Proc.Instance.Marker, Instance_Pool.all);
4694   end Finish_Procedure_Frame;
4695
4696   procedure Execute_If_Statement (Proc : Process_State_Acc; Stmt : Iir)
4697   is
4698      Clause: Iir;
4699      Cond: Boolean;
4700   begin
4701      Clause := Stmt;
4702      loop
4703         Cond := Execute_Condition (Proc.Instance, Get_Condition (Clause));
4704         if Cond then
4705            Init_Sequential_Statements (Proc, Clause);
4706            return;
4707         end if;
4708         Clause := Get_Else_Clause (Clause);
4709         exit when Clause = Null_Iir;
4710      end loop;
4711      Update_Next_Statement (Proc);
4712   end Execute_If_Statement;
4713
4714   procedure Execute_Variable_Assignment (Proc : Process_State_Acc; Stmt : Iir)
4715   is
4716      Instance : constant Block_Instance_Acc := Proc.Instance;
4717      Target : constant Iir := Get_Target (Stmt);
4718      Target_Type : constant Iir := Get_Type (Target);
4719      Expr : constant Iir := Get_Expression (Stmt);
4720      Expr_Type : constant Iir := Get_Type (Expr);
4721      Target_Val: Iir_Value_Literal_Acc;
4722      Res : Iir_Value_Literal_Acc;
4723      Marker : Mark_Type;
4724   begin
4725      Mark (Marker, Expr_Pool);
4726      Target_Val := Execute_Expression (Instance, Target);
4727
4728      --  If the type of the target is not static and the value is
4729      --  an aggregate, then the aggregate may be contrained by the
4730      --  target.
4731      if Get_Kind (Expr) = Iir_Kind_Aggregate
4732        and then Get_Kind (Expr_Type) in Iir_Kinds_Array_Type_Definition
4733      then
4734         Res := Copy_Array_Bound (Target_Val);
4735         Fill_Array_Aggregate (Instance, Expr, Res);
4736      else
4737         Res := Execute_Expression (Instance, Expr);
4738      end if;
4739      if Get_Kind (Target_Type) in Iir_Kinds_Array_Type_Definition then
4740         --  Note: target_type may be dynamic (slice case), so
4741         --  check_constraints is not called.
4742         Implicit_Array_Conversion (Res, Target_Val, Stmt);
4743      else
4744         Check_Constraints (Instance, Res, Target_Type, Stmt);
4745      end if;
4746
4747      --  Note: we need to unshare before copying to avoid
4748      --  overwrites (in assignments like: v (1 to 4) := v (3 to 6)).
4749      --  FIXME: improve that handling (detect overlaps before).
4750      Store (Target_Val, Unshare (Res, Expr_Pool'Access));
4751
4752      Release (Marker, Expr_Pool);
4753   end Execute_Variable_Assignment;
4754
4755   function Execute_Return_Statement (Proc : Process_State_Acc)
4756                                     return Boolean
4757   is
4758      Res : Iir_Value_Literal_Acc;
4759      Instance : constant Block_Instance_Acc := Proc.Instance;
4760      Stmt : constant Iir := Instance.Stmt;
4761      Expr : constant Iir := Get_Expression (Stmt);
4762   begin
4763      if Expr /= Null_Iir then
4764         Res := Execute_Expression (Instance, Expr);
4765         Implicit_Array_Conversion (Instance, Res, Get_Type (Stmt), Stmt);
4766         Check_Constraints (Instance, Res, Get_Type (Stmt), Stmt);
4767         Instance.Result := Res;
4768      end if;
4769
4770      case Get_Kind (Instance.Label) is
4771         when Iir_Kind_Procedure_Declaration =>
4772            Finish_Procedure_Frame (Proc);
4773            Update_Next_Statement (Proc);
4774            return False;
4775         when Iir_Kind_Function_Declaration =>
4776            return True;
4777         when others =>
4778            raise Internal_Error;
4779      end case;
4780   end Execute_Return_Statement;
4781
4782   procedure Finish_Sequential_Statements
4783     (Proc : Process_State_Acc; Complex_Stmt : Iir)
4784   is
4785      Instance : Block_Instance_Acc := Proc.Instance;
4786      Stmt : Iir;
4787   begin
4788      Stmt := Complex_Stmt;
4789      loop
4790         Instance.Stmt := Stmt;
4791         case Get_Kind (Stmt) is
4792            when Iir_Kind_For_Loop_Statement =>
4793               if Finish_For_Loop_Statement (Instance) then
4794                  return;
4795               end if;
4796            when Iir_Kind_While_Loop_Statement =>
4797               if Finish_While_Loop_Statement (Instance) then
4798                  return;
4799               end if;
4800            when Iir_Kind_Case_Statement
4801              | Iir_Kind_If_Statement =>
4802               null;
4803            when Iir_Kind_Sensitized_Process_Statement =>
4804               Instance.Stmt := Null_Iir;
4805               return;
4806            when Iir_Kind_Process_Statement =>
4807               --  Start again.
4808               Instance.Stmt := Get_Sequential_Statement_Chain (Stmt);
4809               return;
4810            when Iir_Kind_Procedure_Body =>
4811               Finish_Procedure_Frame (Proc);
4812               Instance := Proc.Instance;
4813            when Iir_Kind_Function_Body =>
4814               Error_Msg_Exec ("missing return statement in function", Stmt);
4815            when others =>
4816               Error_Kind ("execute_next_statement", Stmt);
4817         end case;
4818         Stmt := Get_Chain (Instance.Stmt);
4819         if Stmt /= Null_Iir then
4820            Instance.Stmt := Stmt;
4821            return;
4822         end if;
4823         Stmt := Get_Parent (Instance.Stmt);
4824      end loop;
4825   end Finish_Sequential_Statements;
4826
4827   procedure Init_Sequential_Statements
4828     (Proc : Process_State_Acc; Complex_Stmt : Iir)
4829   is
4830      Stmt : Iir;
4831   begin
4832      Stmt := Get_Sequential_Statement_Chain (Complex_Stmt);
4833      if Stmt /= Null_Iir then
4834         Proc.Instance.Stmt := Stmt;
4835      else
4836         Finish_Sequential_Statements (Proc, Complex_Stmt);
4837      end if;
4838   end Init_Sequential_Statements;
4839
4840   procedure Update_Next_Statement (Proc : Process_State_Acc)
4841   is
4842      Instance : constant Block_Instance_Acc := Proc.Instance;
4843      Stmt : Iir;
4844   begin
4845      Stmt := Get_Chain (Instance.Stmt);
4846      if Stmt /= Null_Iir then
4847         Instance.Stmt := Stmt;
4848         return;
4849      end if;
4850      Finish_Sequential_Statements (Proc, Get_Parent (Instance.Stmt));
4851   end Update_Next_Statement;
4852
4853   procedure Execute_Sequential_Statements (Proc : Process_State_Acc)
4854   is
4855      Instance : Block_Instance_Acc;
4856      Stmt: Iir;
4857   begin
4858      loop
4859         Instance := Proc.Instance;
4860         Stmt := Instance.Stmt;
4861
4862         --  End of process or subprogram.
4863         exit when Stmt = Null_Iir;
4864
4865         if Trace_Statements then
4866            declare
4867               Name : Name_Id;
4868               Line : Natural;
4869               Col : Natural;
4870            begin
4871               Files_Map.Location_To_Position
4872                 (Get_Location (Stmt), Name, Line, Col);
4873               Put_Line ("Execute statement at "
4874                           & Name_Table.Image (Name)
4875                           & Natural'Image (Line));
4876            end;
4877         end if;
4878
4879         if Flag_Need_Debug then
4880            Debug (Reason_Break);
4881         end if;
4882
4883         -- execute statement STMT.
4884         case Get_Kind (Stmt) is
4885            when Iir_Kind_Null_Statement =>
4886               Update_Next_Statement (Proc);
4887
4888            when Iir_Kind_If_Statement =>
4889               Execute_If_Statement (Proc, Stmt);
4890
4891            when Iir_Kind_Simple_Signal_Assignment_Statement =>
4892               Execute_Signal_Assignment
4893                 (Instance, Stmt, Get_Waveform_Chain (Stmt));
4894               Update_Next_Statement (Proc);
4895
4896            when Iir_Kind_Selected_Waveform_Assignment_Statement =>
4897               declare
4898                  Assoc : Iir;
4899               begin
4900                  Assoc := Execute_Choice (Instance, Get_Expression (Stmt),
4901                                           Get_Selected_Waveform_Chain (Stmt));
4902                  Execute_Signal_Assignment
4903                    (Instance, Stmt, Get_Associated_Chain (Assoc));
4904                  Update_Next_Statement (Proc);
4905               end;
4906            when Iir_Kind_Assertion_Statement =>
4907               declare
4908                  Res : Boolean;
4909               begin
4910                  Res := Execute_Condition
4911                    (Instance, Get_Assertion_Condition (Stmt));
4912                  if not Res then
4913                     Execute_Failed_Assertion (Instance, "assertion", Stmt,
4914                                               "Assertion violation.", 2);
4915                  end if;
4916               end;
4917               Update_Next_Statement (Proc);
4918
4919            when Iir_Kind_Report_Statement =>
4920               Execute_Failed_Assertion (Instance, "report", Stmt,
4921                                         "Assertion violation.", 0);
4922               Update_Next_Statement (Proc);
4923
4924            when Iir_Kind_Variable_Assignment_Statement =>
4925               Execute_Variable_Assignment (Proc, Stmt);
4926               Update_Next_Statement (Proc);
4927
4928            when Iir_Kind_Return_Statement =>
4929               if Execute_Return_Statement (Proc) then
4930                  return;
4931               end if;
4932
4933            when Iir_Kind_For_Loop_Statement =>
4934               Execute_For_Loop_Statement (Proc);
4935
4936            when Iir_Kind_While_Loop_Statement =>
4937               Execute_While_Loop_Statement (Proc);
4938
4939            when Iir_Kind_Case_Statement =>
4940               Execute_Case_Statement (Proc);
4941
4942            when Iir_Kind_Wait_Statement =>
4943               if Execute_Wait_Statement (Instance, Stmt) then
4944                  return;
4945               end if;
4946               Update_Next_Statement (Proc);
4947
4948            when Iir_Kind_Procedure_Call_Statement =>
4949               Execute_Call_Statement (Proc);
4950
4951            when Iir_Kind_Exit_Statement =>
4952               Execute_Exit_Next_Statement (Proc, True);
4953            when Iir_Kind_Next_Statement =>
4954               Execute_Exit_Next_Statement (Proc, False);
4955
4956            when others =>
4957               Error_Kind ("execute_sequential_statements", Stmt);
4958         end case;
4959      end loop;
4960   end Execute_Sequential_Statements;
4961end Simul.Execution;
4962