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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
|
-- Iir to ortho translator.
-- Copyright (C) 2002 - 2014 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 GCC; see the file COPYING. If not, write to the Free
-- Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-- 02111-1307, USA.
package Trans.Chap3 is
-- Translate the subtype of an object, since an object can define
-- a subtype.
-- This can be done only for a declaration.
-- DECL must have an identifier and a type.
procedure Translate_Object_Subtype
(Decl : Iir; With_Vars : Boolean := True);
procedure Elab_Object_Subtype (Def : Iir);
-- Translate the subtype of a literal.
-- This can be done not at declaration time, ie no variables are created
-- for this subtype.
--procedure Translate_Literal_Subtype (Def : Iir);
-- Translation of a type definition or subtype indication.
-- 1. Create corresponding Ortho type.
-- 2. Create bounds type
-- 3. Create bounds declaration
-- 4. Create bounds constructor
-- 5. Create type descriptor declaration
-- 6. Create type descriptor constructor
procedure Translate_Type_Definition (Def : Iir);
-- Translate subprograms for types.
procedure Translate_Type_Subprograms
(Decl : Iir; Kind : Subprg_Translate_Kind);
function Create_Static_Composite_Subtype_Layout (Def : Iir) return O_Cnode;
-- Same as Translate_type_definition only for std.standard.boolean and
-- std.standard.bit.
procedure Translate_Bool_Type_Definition (Def : Iir);
-- Call lock or unlock on a protected object.
procedure Call_Ghdl_Protected_Procedure (Type_Def : Iir; Proc : O_Dnode);
procedure Translate_Protected_Type_Body (Bod : Iir);
procedure Translate_Protected_Type_Body_Subprograms_Spec (Bod : Iir);
procedure Translate_Protected_Type_Body_Subprograms_Body (Bod : Iir);
-- DEF derives (using the Ada meaning) of PARENT_TYPE, ie DEF has new
-- constraints on PARENT_TYPE.
procedure Translate_Subtype_Definition
(Def : Iir; Parent_Type : Iir; With_Vars : Boolean := True);
-- Translate a proper subtype indication.
procedure Translate_Subtype_Indication (Def : Iir; With_Vars : Boolean);
procedure Translate_Named_Subtype_Definition (Def : Iir; Id : Name_Id);
-- When there is no name for the subtype (eg: the subtype of a string or
-- of an aggregate). There is also no type mark.
procedure Translate_Anonymous_Subtype_Definition
(Def : Iir; With_Vars : Boolean);
-- It generates code to do type elaboration.
procedure Elab_Type_Declaration (Decl : Iir);
procedure Elab_Subtype_Declaration (Decl : Iir_Subtype_Declaration);
-- Builders.
-- A complex type is a type whose size is not locally static.
--
-- The most simple example is an unidimensionnl array whose range
-- depends on generics.
--
-- We call first order complex type any array whose bounds are not
-- locally static and whose sub-element size is locally static.
--
-- First order complex type objects are represented by a pointer to an
-- array of sub-element, and the storage area for the array is
-- allocated at run-time.
--
-- Since a sub-element type may be a complex type, a type may be
-- complex because one of its sub-element type is complex.
-- EG, a record type whose one element is a complex array.
--
-- A type may be complex either because it is a first order complex
-- type (ie an array whose bounds are not locally static) or because
-- one of its sub-element type is such a type (this is recursive).
--
-- We call second order complex type a complex type that is not of first
-- order.
-- We call third order complex type a second order complex type which is
-- an array whose bounds are not locally static.
--
-- In a complex type, sub-element of first order complex type are
-- represented by a pointer.
-- Any complex type object (constant, signal, variable, port, generic)
-- is represented by a pointer.
--
-- Creation of a second or third order complex type object consists in
-- allocating the memory and building the object.
-- Building a object consists in setting internal pointers.
--
-- A complex type has always a non-null INFO.C, and its size is computed
-- during elaboration.
--
-- For a second or third order complex type, INFO.C.BUILDER_NEED_FUNC
-- is set to TRUE.
-- Functions for fat array.
-- Fat array are array whose size is not known at compilation time.
-- This corresponds to an unconstrained array or a non locally static
-- constrained array.
-- A fat array is a structure containing 2 fields:
-- * base: a pointer to the data of the array.
-- * bounds: a pointer to a structure containing as many fields as
-- number of dimensions; these fields are a structure describing the
-- range of the dimension.
-- If the element subtype of ARR_TYPE is unbounded, create a fat pointer,
-- set the bounds of it (from ARR), and return it.
-- Otherwise, return a null mnode.
-- Used to build a var for a subelement of ARR.
function Create_Maybe_Fat_Array_Element (Arr : Mnode; Arr_Type : Iir)
return Mnode;
-- If the element subtype of the array is unbounded, set the base of VAR
-- from EL, and return it.
-- Otherwise directly return EL (VAR must be null).
function Assign_Maybe_Fat_Array_Element (Var : Mnode; El : Mnode)
return Mnode;
-- Index array BASE of type ATYPE with INDEX.
-- INDEX must be of type ghdl_index_type, thus no bounds checks are
-- performed.
function Index_Base (Base : Mnode; Atype : Iir; Index : O_Enode)
return Mnode;
-- Index array ARR of type ATYPE with INDEX.
function Index_Array (Arr : Mnode; Atype : Iir; Index : O_Enode)
return Mnode;
-- Same for for slicing.
function Slice_Base (Base : Mnode; Atype : Iir; Index : O_Enode)
return Mnode;
-- Get the length of the array (the number of elements).
function Get_Array_Length (Arr : Mnode; Atype : Iir) return O_Enode;
-- Get the number of elements for bounds BOUNDS. BOUNDS are
-- automatically stabilized if necessary.
function Get_Bounds_Length (Bounds : Mnode; Atype : Iir) return O_Enode;
-- Get the number of elements in array ATYPE.
function Get_Array_Type_Length (Atype : Iir) return O_Enode;
-- Get the base of array or record OBJ. If OBJ is already constrained,
-- return it.
function Get_Composite_Base (Obj : Mnode) return Mnode;
-- Get the base of array or record OBJ; but if OBJ is already constrained,
-- convert it to the base of an unbounded object (so this unboxes the
-- records).
function Get_Composite_Unbounded_Base (Obj : Mnode) return Mnode;
-- Get the bounds of composite ARR (an array or an unbounded record).
function Get_Composite_Bounds (Obj : Mnode) return Mnode;
-- Get the range ot ATYPE.
function Type_To_Range (Atype : Iir) return Mnode;
-- Get length of range R.
function Range_To_Length (R : Mnode) return Mnode;
-- Get direction of range R.
function Range_To_Dir (R : Mnode) return Mnode;
-- Get left/right bounds for range R.
function Range_To_Left (R : Mnode) return Mnode;
function Range_To_Right (R : Mnode) return Mnode;
-- Get range for dimension DIM (1 based) of array bounds B of type
-- ATYPE.
function Bounds_To_Range (B : Mnode; Atype : Iir; Dim : Positive)
return Mnode;
-- Get the range of dimension DIM (1 based) of array ARR of type ATYPE.
function Get_Array_Range (Arr : Mnode; Atype : Iir; Dim : Positive)
return Mnode;
-- Get array/record bounds for type ATYPE.
function Get_Composite_Type_Bounds (Atype : Iir) return Mnode;
-- Return a pointer to the base from bounds_acc ACC.
function Get_Bounds_Acc_Base
(Acc : O_Enode; D_Type : Iir) return O_Enode;
-- Return bounds from layout B.
function Layout_To_Bounds (B : Mnode) return Mnode;
-- From a record layout B, return the layout of element EL. EL must be
-- an unbounded element.
function Record_Layout_To_Element_Layout (B : Mnode; El : Iir) return Mnode;
-- From an unbounded record bounds B, get the bounds for (unbounded)
-- element EL.
function Record_Bounds_To_Element_Bounds (B : Mnode; El : Iir) return Mnode;
-- Return the offset for field EL in record B.
function Record_Layout_To_Element_Offset
(B : Mnode; El : Iir; Kind : Object_Kind_Type) return O_Lnode;
-- From an unbounded array bounds B, get the bounds for the (unbounded)
-- element.
function Array_Bounds_To_Element_Bounds (B : Mnode; Atype : Iir)
return Mnode;
-- Deallocate OBJ.
procedure Gen_Deallocate (Obj : O_Enode);
-- Performs deallocation of PARAM (the parameter of a deallocate call).
procedure Translate_Object_Deallocation (Param : Iir);
-- Copy bounds from SRC to DEST.
procedure Copy_Bounds (Dest : O_Enode; Src : O_Enode; Obj_Type : Iir);
procedure Copy_Bounds (Dest : Mnode; Src : Mnode; Obj_Type : Iir);
-- Allocate an object of type OBJ_TYPE and set RES.
-- RES must be a stable access of type ortho_ptr_type.
-- For an unconstrained array, BOUNDS is a pointer to the boundaries of
-- the object, which are copied.
procedure Translate_Object_Allocation
(Res : in out Mnode;
Alloc_Kind : Allocation_Kind;
Obj_Type : Iir;
Bounds : Mnode);
-- Low level copy of SRC to DEST. Both have the same type, OBJ_TYPE.
-- There is no length check, so arrays must be of the same length.
procedure Translate_Object_Copy
(Dest : Mnode; Src : O_Enode; Obj_Type : Iir);
-- Get size (in bytes with type ghdl_index_type) of subtype ATYPE.
-- For an unconstrained array, BOUNDS must be set, otherwise it may be a
-- null_mnode.
function Get_Subtype_Size
(Atype : Iir; Bounds : Mnode; Kind : Object_Kind_Type) return O_Enode;
-- Get size (in bytes with type ghdl_index_type) of object OBJ.
-- For an unconstrained array, OBJ must be really an object, otherwise,
-- it may be the result of T2M.
function Get_Object_Size (Obj : Mnode; Obj_Type : Iir) return O_Enode;
-- Allocate the base of an unbounded composite, whose length is
-- determined from the bounds (already set).
-- RES_PTR is a pointer to the fat pointer (must be a stable variable: it
-- can be referenced several times).
-- ARR_TYPE is the type of the composite.
procedure Allocate_Unbounded_Composite_Base (Alloc_Kind : Allocation_Kind;
Res : Mnode;
Arr_Type : Iir);
-- Allocate the bounds for type OBJ_TYPE and assign it to unbounded object
-- RES. Then copy bounds from BOUNDS to the object.
procedure Allocate_Unbounded_Composite_Bounds
(Alloc_Kind : Allocation_Kind;
Res : Mnode;
Obj_Type : Iir);
-- Used for alias: create the vars for the subtype of the name (when the
-- name is a slice). The identifier prefix must have been set.
procedure Translate_Array_Subtype (Arr_Type : Iir);
procedure Elab_Array_Subtype (Arr_Type : Iir);
-- Create the bounds for SUB_TYPE.
-- SUB_TYPE is expected to be a non-static, anonymous array type.
procedure Create_Array_Subtype (Sub_Type : Iir);
-- Return TRUE if VALUE is not is the range specified by ATYPE.
-- VALUE must be stable.
function Not_In_Range (Value : O_Dnode; Atype : Iir) return O_Enode;
-- Return TRUE if base type of ATYPE is larger than its bounds, ie
-- if a value of type ATYPE may be out of range.
function Need_Range_Check (Expr : Iir; Atype : Iir) return Boolean;
-- Generate an error if VALUE (computed from EXPR which may be NULL_IIR
-- if not from a tree) is not in range specified by ATYPE.
procedure Check_Range
(Value : O_Dnode; Expr : Iir; Atype : Iir; Loc : Iir);
-- Insert a scalar check for VALUE of type ATYPE. EXPR may be NULL_IIR.
function Insert_Scalar_Check
(Value : O_Enode; Expr : Iir; Atype : Iir; Loc : Iir) return O_Enode;
-- The base type of EXPR and the base type of ATYPE must be the same.
-- If the type is a scalar type, and if a range check is needed, this
-- function inserts the check. Otherwise, it returns VALUE.
function Maybe_Insert_Scalar_Check
(Value : O_Enode; Expr : Iir; Atype : Iir) return O_Enode;
-- Return True iff all indexes of L_TYPE and R_TYPE have the same
-- length. They must be locally static.
function Locally_Array_Match (L_Type, R_Type : Iir) return Boolean;
-- Check bounds length of L match bounds length of R.
-- If L_TYPE (resp. R_TYPE) is not a thin array, then L_NODE
-- (resp. R_NODE) are not used (and may be Mnode_Null).
-- If L_TYPE (resp. T_TYPE) is a fat array, then L_NODE (resp. R_NODE)
-- must designate the array.
procedure Check_Array_Match
(L_Type : Iir; L_Node : Mnode; R_Type : Iir; R_Node : Mnode; Loc : Iir);
-- Create a subtype range to be stored into RES from length LENGTH, which
-- is of type INDEX_TYPE.
-- This is done according to rules 7.2.4 of LRM93, ie:
-- direction and left bound of the range is the same of INDEX_TYPE.
-- LENGTH is a variable. LOC is the location in case of error.
procedure Create_Range_From_Length
(Index_Type : Iir; Length : O_Dnode; Res : Mnode; Loc : Iir);
end Trans.Chap3;
|