summaryrefslogtreecommitdiff
path: root/evaluation.ads
blob: 66ec2a1cc305a3418e82431412c9e1112d9a583b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
--  Evaluation of static expressions.
--  Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold
--
--  GHDL is free software; you can redistribute it and/or modify it under
--  the terms of the GNU General Public License as published by the Free
--  Software Foundation; either version 2, or (at your option) any later
--  version.
--
--  GHDL is distributed in the hope that it will be useful, but WITHOUT ANY
--  WARRANTY; without even the implied warranty of MERCHANTABILITY or
--  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
--  for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with GHDL; see the file COPYING.  If not, write to the Free
--  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
--  02111-1307, USA.
with Types; use Types;
with Iirs; use Iirs;

package Evaluation is

   --  Evaluation is about compile-time computation of expressions, such as
   --  2 + 1 --> 3.  This is (of course) possible only with locally (and some
   --  globally) static expressions.  Evaluation is required during semantic
   --  analysis at many places (in fact those where locally static expression
   --  are required by the language).  For example, the type of O'Range (N)
   --  depends on N, so we need to evaluate N.
   --
   --  The result of evaluation is a literal (integer, enumeration, real,
   --  physical), a string or a simple aggregate.  For scalar types, the
   --  result is therefore normalized (there is only one kind of result), but
   --  for array types, the result isn't: in general it will be a string, but
   --  it may be a simple aggregate.  Strings are preferred (because they are
   --  more compact), but aren't possible in some cases.  For example, the
   --  evaluation of "Text" & NUL cannot be a string.
   --
   --  Some functions (like Eval_Static_Expr) simply returns a result (which
   --  may be a node of the expression), others returns a result and set the
   --  origin (Literal_Origin or Range_Origin) to remember the original
   --  expression that was evaluation.  The original expression is kept so that
   --  it is possible to print the original tree.

   --  Get the value of a physical integer literal or unit.
   function Get_Physical_Value (Expr : Iir) return Iir_Int64;

   --  Evaluate the locally static expression EXPR (without checking that EXPR
   --  is locally static).  Return a literal or an aggregate, without setting
   --  the origin, and do not modify EXPR.  This can be used only to get the
   --  value of an expression, without replacing it.
   function Eval_Static_Expr (Expr: Iir) return Iir;

   --  Evaluate (ie compute) expression EXPR.
   --  EXPR is required to be a locally static expression, otherwise an error
   --  message is generated.
   --  The result is a literal with the origin set.
   function Eval_Expr (Expr: Iir) return Iir;

   --  Same as Eval_Expr, but if EXPR is not locally static, the result is
   --  EXPR.  Also, if EXPR is null_iir, then null_iir is returned.
   --  The purpose of this function is to evaluate an expression only if it
   --  is locally static.
   function Eval_Expr_If_Static (Expr : Iir) return Iir;

   --  Evaluate a physical literal and return a normalized literal (using
   --  the primary unit as unit).
   function Eval_Physical_Literal (Expr : Iir) return Iir;

   --  Return TRUE if literal EXPR is in SUB_TYPE bounds.
   function Eval_Is_In_Bound (Expr : Iir; Sub_Type : Iir) return Boolean;

   --  Emit an error if EXPR violates SUB_TYPE bounds.
   procedure Eval_Check_Bound (Expr : Iir; Sub_Type : Iir);

   --  Same as Eval_Expr, but a range check with SUB_TYPE is performed after
   --  computation.
   function Eval_Expr_Check (Expr : Iir; Sub_Type : Iir) return Iir;

   --  Call Eval_Expr_Check only if EXPR is static.
   function Eval_Expr_Check_If_Static (Expr : Iir; Atype : Iir) return Iir;

   --  For a locally static range RNG (a range expression, a range attribute
   --  or a name that denotes a type or a subtype) returns its corresponding
   --  locally static range_expression.  The bounds of the results are also
   --  literals.
   --  Return a range_expression or NULL_IIR for a non locally static range.
   function Eval_Static_Range (Rng : Iir) return Iir;

   --  Return a locally static range expression with the origin set for ARANGE.
   function Eval_Range (Arange : Iir) return Iir;

   --  If ARANGE is a locally static range, return locally static range
   --  expression (with the origin set), else return ARANGE.
   function Eval_Range_If_Static (Arange : Iir) return Iir;

   --  Emit an error if A_RANGE is not included in SUB_TYPE.  A_RANGE can be
   --  a range expression, a range attribute or a name that denotes a discrete
   --  type or subtype.  A_RANGE must be a locally static range.
   procedure Eval_Check_Range (A_Range : Iir; Sub_Type : Iir;
                               Any_Dir : Boolean);

   --  Return TRUE if range expression A_RANGE is not included in SUB_TYPE.
   function Eval_Is_Range_In_Bound
     (A_Range : Iir; Sub_Type : Iir; Any_Dir : Boolean)
     return Boolean;

   --  Return TRUE iff VAL belongs to BOUND.
   function Eval_Int_In_Range (Val : Iir_Int64; Bound : Iir) return Boolean;

   --  Return the length of the discrete range CONSTRAINT.
   function Eval_Discrete_Range_Length (Constraint : Iir) return Iir_Int64;

   --  Return the length of SUB_TYPE.
   function Eval_Discrete_Type_Length (Sub_Type : Iir) return Iir_Int64;

   --  Get the left bound of a range constraint.
   --  Note: the range constraint may be an attribute or a subtype.
   function Eval_Discrete_Range_Left (Constraint : Iir) return Iir;

   --  Return the position of EXPR, ie the result of sub_type'pos (EXPR), where
   --  sub_type is the type of expr.
   --  EXPR must be of a discrete subtype.
   function Eval_Pos (Expr : Iir) return Iir_Int64;

   --  Replace ORIGIN (an overflow literal) with extreme positive value (if
   --  IS_POS is true) or extreme negative value.
   function Build_Extreme_Value (Is_Pos : Boolean; Origin : Iir) return Iir;

   --  Create an array subtype from LEN and BASE_TYPE, according to rules
   --  of LRM93 7.3.2.2. (which are the same as LRM93 7.2.4).
   function Create_Unidim_Array_By_Length
     (Base_Type : Iir; Len : Iir_Int64; Loc : Iir)
     return Iir_Array_Subtype_Definition;

   --  Create a subtype of A_TYPE whose length is LEN.
   --  This is used to create subtypes for strings or aggregates.
   function Create_Range_Subtype_By_Length
     (A_Type : Iir; Len : Iir_Int64; Loc : Location_Type)
     return Iir;

   --  Store into NAME_BUFFER, NAME_LENGTH the simple name, character literal
   --  or operator sumbol of ID, using the same format as SIMPLE_NAME
   --  attribute.
   procedure Eval_Simple_Name (Id : Name_Id);

   --  Compare two string literals (of same length).
   type Compare_Type is (Compare_Lt, Compare_Eq, Compare_Gt);
   function Compare_String_Literals (L, R : Iir) return Compare_Type;

   --  Return the local part of 'Instance_Name or 'Path_Name.
   type Path_Instance_Name_Type (Len : Natural) is record
      --  The node before suffix (entity, architecture or generate iterator).
      Path_Instance : Iir;

      --  The suffix
      Suffix : String (1 .. Len);
   end record;

   function Get_Path_Instance_Name_Suffix (Attr : Iir)
                                          return Path_Instance_Name_Type;
end Evaluation;