annotate gcc/ada/exp_code.adb @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- E X P _ C O D E --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 1996-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Atree; use Atree;
kono
parents:
diff changeset
27 with Einfo; use Einfo;
kono
parents:
diff changeset
28 with Errout; use Errout;
kono
parents:
diff changeset
29 with Lib; use Lib;
kono
parents:
diff changeset
30 with Namet; use Namet;
kono
parents:
diff changeset
31 with Nlists; use Nlists;
kono
parents:
diff changeset
32 with Nmake; use Nmake;
kono
parents:
diff changeset
33 with Opt; use Opt;
kono
parents:
diff changeset
34 with Rtsfind; use Rtsfind;
kono
parents:
diff changeset
35 with Sem_Aux; use Sem_Aux;
kono
parents:
diff changeset
36 with Sem_Eval; use Sem_Eval;
kono
parents:
diff changeset
37 with Sem_Util; use Sem_Util;
kono
parents:
diff changeset
38 with Sem_Warn; use Sem_Warn;
kono
parents:
diff changeset
39 with Sinfo; use Sinfo;
kono
parents:
diff changeset
40 with Stringt; use Stringt;
kono
parents:
diff changeset
41 with Tbuild; use Tbuild;
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 package body Exp_Code is
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 -----------------------
kono
parents:
diff changeset
46 -- Local_Subprograms --
kono
parents:
diff changeset
47 -----------------------
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 function Asm_Constraint (Operand_Var : Node_Id) return Node_Id;
kono
parents:
diff changeset
50 -- Common processing for Asm_Input_Constraint and Asm_Output_Constraint.
kono
parents:
diff changeset
51 -- Obtains the constraint argument from the global operand variable
kono
parents:
diff changeset
52 -- Operand_Var, which must be non-Empty.
kono
parents:
diff changeset
53
kono
parents:
diff changeset
54 function Asm_Operand (Operand_Var : Node_Id) return Node_Id;
kono
parents:
diff changeset
55 -- Common processing for Asm_Input_Value and Asm_Output_Variable. Obtains
kono
parents:
diff changeset
56 -- the value/variable argument from Operand_Var, the global operand
kono
parents:
diff changeset
57 -- variable. Returns Empty if no operand available.
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 function Get_String_Node (S : Node_Id) return Node_Id;
kono
parents:
diff changeset
60 -- Given S, a static expression node of type String, returns the
kono
parents:
diff changeset
61 -- string literal node. This is needed to deal with the use of constants
kono
parents:
diff changeset
62 -- for these expressions, which is perfectly permissible.
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 procedure Next_Asm_Operand (Operand_Var : in out Node_Id);
kono
parents:
diff changeset
65 -- Common processing for Next_Asm_Input and Next_Asm_Output, updates
kono
parents:
diff changeset
66 -- the value of the global operand variable Operand_Var appropriately.
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 procedure Setup_Asm_IO_Args (Arg : Node_Id; Operand_Var : out Node_Id);
kono
parents:
diff changeset
69 -- Common processing for Setup_Asm_Inputs and Setup_Asm_Outputs. Arg
kono
parents:
diff changeset
70 -- is the actual parameter from the call, and Operand_Var is the global
kono
parents:
diff changeset
71 -- operand variable to be initialized to the first operand.
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 ----------------------
kono
parents:
diff changeset
74 -- Global Variables --
kono
parents:
diff changeset
75 ----------------------
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 Current_Input_Operand : Node_Id := Empty;
kono
parents:
diff changeset
78 -- Points to current Asm_Input_Operand attribute reference. Initialized
kono
parents:
diff changeset
79 -- by Setup_Asm_Inputs, updated by Next_Asm_Input, and referenced by
kono
parents:
diff changeset
80 -- Asm_Input_Constraint and Asm_Input_Value.
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 Current_Output_Operand : Node_Id := Empty;
kono
parents:
diff changeset
83 -- Points to current Asm_Output_Operand attribute reference. Initialized
kono
parents:
diff changeset
84 -- by Setup_Asm_Outputs, updated by Next_Asm_Output, and referenced by
kono
parents:
diff changeset
85 -- Asm_Output_Constraint and Asm_Output_Variable.
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 --------------------
kono
parents:
diff changeset
88 -- Asm_Constraint --
kono
parents:
diff changeset
89 --------------------
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 function Asm_Constraint (Operand_Var : Node_Id) return Node_Id is
kono
parents:
diff changeset
92 begin
kono
parents:
diff changeset
93 pragma Assert (Present (Operand_Var));
kono
parents:
diff changeset
94 return Get_String_Node (First (Expressions (Operand_Var)));
kono
parents:
diff changeset
95 end Asm_Constraint;
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 --------------------------
kono
parents:
diff changeset
98 -- Asm_Input_Constraint --
kono
parents:
diff changeset
99 --------------------------
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 -- Note: error checking on Asm_Input attribute done in Sem_Attr
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 function Asm_Input_Constraint return Node_Id is
kono
parents:
diff changeset
104 begin
kono
parents:
diff changeset
105 return Get_String_Node (Asm_Constraint (Current_Input_Operand));
kono
parents:
diff changeset
106 end Asm_Input_Constraint;
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 ---------------------
kono
parents:
diff changeset
109 -- Asm_Input_Value --
kono
parents:
diff changeset
110 ---------------------
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 -- Note: error checking on Asm_Input attribute done in Sem_Attr
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 function Asm_Input_Value return Node_Id is
kono
parents:
diff changeset
115 begin
kono
parents:
diff changeset
116 return Asm_Operand (Current_Input_Operand);
kono
parents:
diff changeset
117 end Asm_Input_Value;
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 -----------------
kono
parents:
diff changeset
120 -- Asm_Operand --
kono
parents:
diff changeset
121 -----------------
kono
parents:
diff changeset
122
kono
parents:
diff changeset
123 function Asm_Operand (Operand_Var : Node_Id) return Node_Id is
kono
parents:
diff changeset
124 begin
kono
parents:
diff changeset
125 if No (Operand_Var) then
kono
parents:
diff changeset
126 return Empty;
kono
parents:
diff changeset
127 elsif Error_Posted (Operand_Var) then
kono
parents:
diff changeset
128 return Error;
kono
parents:
diff changeset
129 else
kono
parents:
diff changeset
130 return Next (First (Expressions (Operand_Var)));
kono
parents:
diff changeset
131 end if;
kono
parents:
diff changeset
132 end Asm_Operand;
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 ---------------------------
kono
parents:
diff changeset
135 -- Asm_Output_Constraint --
kono
parents:
diff changeset
136 ---------------------------
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 -- Note: error checking on Asm_Output attribute done in Sem_Attr
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 function Asm_Output_Constraint return Node_Id is
kono
parents:
diff changeset
141 begin
kono
parents:
diff changeset
142 return Asm_Constraint (Current_Output_Operand);
kono
parents:
diff changeset
143 end Asm_Output_Constraint;
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 -------------------------
kono
parents:
diff changeset
146 -- Asm_Output_Variable --
kono
parents:
diff changeset
147 -------------------------
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 -- Note: error checking on Asm_Output attribute done in Sem_Attr
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 function Asm_Output_Variable return Node_Id is
kono
parents:
diff changeset
152 begin
kono
parents:
diff changeset
153 return Asm_Operand (Current_Output_Operand);
kono
parents:
diff changeset
154 end Asm_Output_Variable;
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 ------------------
kono
parents:
diff changeset
157 -- Asm_Template --
kono
parents:
diff changeset
158 ------------------
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 function Asm_Template (N : Node_Id) return Node_Id is
kono
parents:
diff changeset
161 Call : constant Node_Id := Expression (Expression (N));
kono
parents:
diff changeset
162 Temp : constant Node_Id := First_Actual (Call);
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 begin
kono
parents:
diff changeset
165 -- Require static expression for template. We also allow a string
kono
parents:
diff changeset
166 -- literal (this is useful for Ada 83 mode where string expressions
kono
parents:
diff changeset
167 -- are never static).
kono
parents:
diff changeset
168
kono
parents:
diff changeset
169 if Is_OK_Static_Expression (Temp)
kono
parents:
diff changeset
170 or else (Ada_Version = Ada_83
kono
parents:
diff changeset
171 and then Nkind (Temp) = N_String_Literal)
kono
parents:
diff changeset
172 then
kono
parents:
diff changeset
173 return Get_String_Node (Temp);
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 else
kono
parents:
diff changeset
176 Flag_Non_Static_Expr ("asm template argument is not static!", Temp);
kono
parents:
diff changeset
177 return Empty;
kono
parents:
diff changeset
178 end if;
kono
parents:
diff changeset
179 end Asm_Template;
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 ----------------------
kono
parents:
diff changeset
182 -- Clobber_Get_Next --
kono
parents:
diff changeset
183 ----------------------
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 Clobber_Node : Node_Id;
kono
parents:
diff changeset
186 -- String literal node for clobber string. Initialized by Clobber_Setup,
kono
parents:
diff changeset
187 -- and not modified by Clobber_Get_Next. Empty if clobber string was in
kono
parents:
diff changeset
188 -- error (resulting in no clobber arguments being returned).
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 Clobber_Ptr : Pos;
kono
parents:
diff changeset
191 -- Pointer to current character of string. Initialized to 1 by the call
kono
parents:
diff changeset
192 -- to Clobber_Setup, and then updated by Clobber_Get_Next.
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 function Clobber_Get_Next return Address is
kono
parents:
diff changeset
195 Str : constant String_Id := Strval (Clobber_Node);
kono
parents:
diff changeset
196 Len : constant Nat := String_Length (Str);
kono
parents:
diff changeset
197 C : Character;
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 begin
kono
parents:
diff changeset
200 if No (Clobber_Node) then
kono
parents:
diff changeset
201 return Null_Address;
kono
parents:
diff changeset
202 end if;
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 -- Skip spaces and commas before next register name
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 loop
kono
parents:
diff changeset
207 -- Return null string if no more names
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 if Clobber_Ptr > Len then
kono
parents:
diff changeset
210 return Null_Address;
kono
parents:
diff changeset
211 end if;
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 C := Get_Character (Get_String_Char (Str, Clobber_Ptr));
kono
parents:
diff changeset
214 exit when C /= ',' and then C /= ' ';
kono
parents:
diff changeset
215 Clobber_Ptr := Clobber_Ptr + 1;
kono
parents:
diff changeset
216 end loop;
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 -- Acquire next register name
kono
parents:
diff changeset
219
kono
parents:
diff changeset
220 Name_Len := 0;
kono
parents:
diff changeset
221 loop
kono
parents:
diff changeset
222 Add_Char_To_Name_Buffer (C);
kono
parents:
diff changeset
223 Clobber_Ptr := Clobber_Ptr + 1;
kono
parents:
diff changeset
224 exit when Clobber_Ptr > Len;
kono
parents:
diff changeset
225 C := Get_Character (Get_String_Char (Str, Clobber_Ptr));
kono
parents:
diff changeset
226 exit when C = ',' or else C = ' ';
kono
parents:
diff changeset
227 end loop;
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 Name_Buffer (Name_Len + 1) := ASCII.NUL;
kono
parents:
diff changeset
230 return Name_Buffer'Address;
kono
parents:
diff changeset
231 end Clobber_Get_Next;
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 -------------------
kono
parents:
diff changeset
234 -- Clobber_Setup --
kono
parents:
diff changeset
235 -------------------
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 procedure Clobber_Setup (N : Node_Id) is
kono
parents:
diff changeset
238 Call : constant Node_Id := Expression (Expression (N));
kono
parents:
diff changeset
239 Clob : constant Node_Id := Next_Actual (
kono
parents:
diff changeset
240 Next_Actual (
kono
parents:
diff changeset
241 Next_Actual (
kono
parents:
diff changeset
242 First_Actual (Call))));
kono
parents:
diff changeset
243 begin
kono
parents:
diff changeset
244 if not Is_OK_Static_Expression (Clob) then
kono
parents:
diff changeset
245 Flag_Non_Static_Expr ("asm clobber argument is not static!", Clob);
kono
parents:
diff changeset
246 Clobber_Node := Empty;
kono
parents:
diff changeset
247 else
kono
parents:
diff changeset
248 Clobber_Node := Get_String_Node (Clob);
kono
parents:
diff changeset
249 Clobber_Ptr := 1;
kono
parents:
diff changeset
250 end if;
kono
parents:
diff changeset
251 end Clobber_Setup;
kono
parents:
diff changeset
252
kono
parents:
diff changeset
253 ---------------------
kono
parents:
diff changeset
254 -- Expand_Asm_Call --
kono
parents:
diff changeset
255 ---------------------
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 procedure Expand_Asm_Call (N : Node_Id) is
kono
parents:
diff changeset
258 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 procedure Check_IO_Operand (N : Node_Id);
kono
parents:
diff changeset
261 -- Check for incorrect input or output operand
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263 ----------------------
kono
parents:
diff changeset
264 -- Check_IO_Operand --
kono
parents:
diff changeset
265 ----------------------
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 procedure Check_IO_Operand (N : Node_Id) is
kono
parents:
diff changeset
268 Err : Node_Id := N;
kono
parents:
diff changeset
269
kono
parents:
diff changeset
270 begin
kono
parents:
diff changeset
271 -- The only identifier allowed is No_xxput_Operands. Since we
kono
parents:
diff changeset
272 -- know the type is right, it is sufficient to see if the
kono
parents:
diff changeset
273 -- referenced entity is in a runtime routine.
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 if Is_Entity_Name (N)
kono
parents:
diff changeset
276 and then Is_Predefined_Unit (Get_Source_Unit (Entity (N)))
kono
parents:
diff changeset
277 then
kono
parents:
diff changeset
278 return;
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 -- An attribute reference is fine, again the analysis reasonably
kono
parents:
diff changeset
281 -- guarantees that the attribute must be subtype'Asm_??put.
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 elsif Nkind (N) = N_Attribute_Reference then
kono
parents:
diff changeset
284 return;
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 -- The only other allowed form is an array aggregate in which
kono
parents:
diff changeset
287 -- all the entries are positional and are attribute references.
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 elsif Nkind (N) = N_Aggregate then
kono
parents:
diff changeset
290 if Present (Component_Associations (N)) then
kono
parents:
diff changeset
291 Err := First (Component_Associations (N));
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 elsif Present (Expressions (N)) then
kono
parents:
diff changeset
294 Err := First (Expressions (N));
kono
parents:
diff changeset
295 while Present (Err) loop
kono
parents:
diff changeset
296 exit when Nkind (Err) /= N_Attribute_Reference;
kono
parents:
diff changeset
297 Next (Err);
kono
parents:
diff changeset
298 end loop;
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 if No (Err) then
kono
parents:
diff changeset
301 return;
kono
parents:
diff changeset
302 end if;
kono
parents:
diff changeset
303 end if;
kono
parents:
diff changeset
304 end if;
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 -- If we fall through, Err is pointing to the bad node
kono
parents:
diff changeset
307
kono
parents:
diff changeset
308 Error_Msg_N ("Asm operand has wrong form", Err);
kono
parents:
diff changeset
309 end Check_IO_Operand;
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 -- Start of processing for Expand_Asm_Call
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 begin
kono
parents:
diff changeset
314 -- Check that the input and output operands have the right
kono
parents:
diff changeset
315 -- form, as required by the documentation of the Asm feature:
kono
parents:
diff changeset
316
kono
parents:
diff changeset
317 -- OUTPUT_OPERAND_LIST ::=
kono
parents:
diff changeset
318 -- No_Output_Operands
kono
parents:
diff changeset
319 -- | OUTPUT_OPERAND_ATTRIBUTE
kono
parents:
diff changeset
320 -- | (OUTPUT_OPERAND_ATTRIBUTE @{,OUTPUT_OPERAND_ATTRIBUTE@})
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 -- OUTPUT_OPERAND_ATTRIBUTE ::=
kono
parents:
diff changeset
323 -- SUBTYPE_MARK'Asm_Output (static_string_EXPRESSION, NAME)
kono
parents:
diff changeset
324
kono
parents:
diff changeset
325 -- INPUT_OPERAND_LIST ::=
kono
parents:
diff changeset
326 -- No_Input_Operands
kono
parents:
diff changeset
327 -- | INPUT_OPERAND_ATTRIBUTE
kono
parents:
diff changeset
328 -- | (INPUT_OPERAND_ATTRIBUTE @{,INPUT_OPERAND_ATTRIBUTE@})
kono
parents:
diff changeset
329
kono
parents:
diff changeset
330 -- INPUT_OPERAND_ATTRIBUTE ::=
kono
parents:
diff changeset
331 -- SUBTYPE_MARK'Asm_Input (static_string_EXPRESSION, EXPRESSION)
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 declare
kono
parents:
diff changeset
334 Arg_Output : constant Node_Id := Next_Actual (First_Actual (N));
kono
parents:
diff changeset
335 Arg_Input : constant Node_Id := Next_Actual (Arg_Output);
kono
parents:
diff changeset
336 begin
kono
parents:
diff changeset
337 Check_IO_Operand (Arg_Output);
kono
parents:
diff changeset
338 Check_IO_Operand (Arg_Input);
kono
parents:
diff changeset
339 end;
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 -- If we have the function call case, we are inside a code statement,
kono
parents:
diff changeset
342 -- and the tree is already in the necessary form for gigi.
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 if Nkind (N) = N_Function_Call then
kono
parents:
diff changeset
345 null;
kono
parents:
diff changeset
346
kono
parents:
diff changeset
347 -- For the procedure case, we convert the call into a code statement
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 else
kono
parents:
diff changeset
350 pragma Assert (Nkind (N) = N_Procedure_Call_Statement);
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 -- Note: strictly we should change the procedure call to a function
kono
parents:
diff changeset
353 -- call in the qualified expression, but since we are not going to
kono
parents:
diff changeset
354 -- reanalyze (see below), and the interface subprograms in this
kono
parents:
diff changeset
355 -- package don't care, we can leave it as a procedure call.
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 Rewrite (N,
kono
parents:
diff changeset
358 Make_Code_Statement (Loc,
kono
parents:
diff changeset
359 Expression =>
kono
parents:
diff changeset
360 Make_Qualified_Expression (Loc,
kono
parents:
diff changeset
361 Subtype_Mark => New_Occurrence_Of (RTE (RE_Asm_Insn), Loc),
kono
parents:
diff changeset
362 Expression => Relocate_Node (N))));
kono
parents:
diff changeset
363
kono
parents:
diff changeset
364 -- There is no need to reanalyze this node, it is completely analyzed
kono
parents:
diff changeset
365 -- already, at least sufficiently for the purposes of the abstract
kono
parents:
diff changeset
366 -- procedural interface defined in this package. Furthermore if we
kono
parents:
diff changeset
367 -- let it go through the normal analysis, that would include some
kono
parents:
diff changeset
368 -- inappropriate checks that apply only to explicit code statements
kono
parents:
diff changeset
369 -- in the source, and not to calls to intrinsics.
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 Set_Analyzed (N);
kono
parents:
diff changeset
372 Check_Code_Statement (N);
kono
parents:
diff changeset
373 end if;
kono
parents:
diff changeset
374 end Expand_Asm_Call;
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 ---------------------
kono
parents:
diff changeset
377 -- Get_String_Node --
kono
parents:
diff changeset
378 ---------------------
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 function Get_String_Node (S : Node_Id) return Node_Id is
kono
parents:
diff changeset
381 begin
kono
parents:
diff changeset
382 if Nkind (S) = N_String_Literal then
kono
parents:
diff changeset
383 return S;
kono
parents:
diff changeset
384 else
kono
parents:
diff changeset
385 pragma Assert (Ekind (Entity (S)) = E_Constant);
kono
parents:
diff changeset
386 return Get_String_Node (Constant_Value (Entity (S)));
kono
parents:
diff changeset
387 end if;
kono
parents:
diff changeset
388 end Get_String_Node;
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 ---------------------
kono
parents:
diff changeset
391 -- Is_Asm_Volatile --
kono
parents:
diff changeset
392 ---------------------
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 function Is_Asm_Volatile (N : Node_Id) return Boolean is
kono
parents:
diff changeset
395 Call : constant Node_Id := Expression (Expression (N));
kono
parents:
diff changeset
396 Vol : constant Node_Id :=
kono
parents:
diff changeset
397 Next_Actual (
kono
parents:
diff changeset
398 Next_Actual (
kono
parents:
diff changeset
399 Next_Actual (
kono
parents:
diff changeset
400 Next_Actual (
kono
parents:
diff changeset
401 First_Actual (Call)))));
kono
parents:
diff changeset
402 begin
kono
parents:
diff changeset
403 if not Is_OK_Static_Expression (Vol) then
kono
parents:
diff changeset
404 Flag_Non_Static_Expr ("asm volatile argument is not static!", Vol);
kono
parents:
diff changeset
405 return False;
kono
parents:
diff changeset
406 else
kono
parents:
diff changeset
407 return Is_True (Expr_Value (Vol));
kono
parents:
diff changeset
408 end if;
kono
parents:
diff changeset
409 end Is_Asm_Volatile;
kono
parents:
diff changeset
410
kono
parents:
diff changeset
411 --------------------
kono
parents:
diff changeset
412 -- Next_Asm_Input --
kono
parents:
diff changeset
413 --------------------
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 procedure Next_Asm_Input is
kono
parents:
diff changeset
416 begin
kono
parents:
diff changeset
417 Next_Asm_Operand (Current_Input_Operand);
kono
parents:
diff changeset
418 end Next_Asm_Input;
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 ----------------------
kono
parents:
diff changeset
421 -- Next_Asm_Operand --
kono
parents:
diff changeset
422 ----------------------
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 procedure Next_Asm_Operand (Operand_Var : in out Node_Id) is
kono
parents:
diff changeset
425 begin
kono
parents:
diff changeset
426 pragma Assert (Present (Operand_Var));
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 if Nkind (Parent (Operand_Var)) = N_Aggregate then
kono
parents:
diff changeset
429 Operand_Var := Next (Operand_Var);
kono
parents:
diff changeset
430 else
kono
parents:
diff changeset
431 Operand_Var := Empty;
kono
parents:
diff changeset
432 end if;
kono
parents:
diff changeset
433 end Next_Asm_Operand;
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 ---------------------
kono
parents:
diff changeset
436 -- Next_Asm_Output --
kono
parents:
diff changeset
437 ---------------------
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 procedure Next_Asm_Output is
kono
parents:
diff changeset
440 begin
kono
parents:
diff changeset
441 Next_Asm_Operand (Current_Output_Operand);
kono
parents:
diff changeset
442 end Next_Asm_Output;
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 ----------------------
kono
parents:
diff changeset
445 -- Setup_Asm_Inputs --
kono
parents:
diff changeset
446 ----------------------
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 procedure Setup_Asm_Inputs (N : Node_Id) is
kono
parents:
diff changeset
449 Call : constant Node_Id := Expression (Expression (N));
kono
parents:
diff changeset
450 begin
kono
parents:
diff changeset
451 Setup_Asm_IO_Args
kono
parents:
diff changeset
452 (Next_Actual (Next_Actual (First_Actual (Call))),
kono
parents:
diff changeset
453 Current_Input_Operand);
kono
parents:
diff changeset
454 end Setup_Asm_Inputs;
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 -----------------------
kono
parents:
diff changeset
457 -- Setup_Asm_IO_Args --
kono
parents:
diff changeset
458 -----------------------
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 procedure Setup_Asm_IO_Args (Arg : Node_Id; Operand_Var : out Node_Id) is
kono
parents:
diff changeset
461 begin
kono
parents:
diff changeset
462 -- Case of single argument
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 if Nkind (Arg) = N_Attribute_Reference then
kono
parents:
diff changeset
465 Operand_Var := Arg;
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 -- Case of list of arguments
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 elsif Nkind (Arg) = N_Aggregate then
kono
parents:
diff changeset
470 if Expressions (Arg) = No_List then
kono
parents:
diff changeset
471 Operand_Var := Empty;
kono
parents:
diff changeset
472 else
kono
parents:
diff changeset
473 Operand_Var := First (Expressions (Arg));
kono
parents:
diff changeset
474 end if;
kono
parents:
diff changeset
475
kono
parents:
diff changeset
476 -- Otherwise must be default (no operands) case
kono
parents:
diff changeset
477
kono
parents:
diff changeset
478 else
kono
parents:
diff changeset
479 Operand_Var := Empty;
kono
parents:
diff changeset
480 end if;
kono
parents:
diff changeset
481 end Setup_Asm_IO_Args;
kono
parents:
diff changeset
482
kono
parents:
diff changeset
483 -----------------------
kono
parents:
diff changeset
484 -- Setup_Asm_Outputs --
kono
parents:
diff changeset
485 -----------------------
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 procedure Setup_Asm_Outputs (N : Node_Id) is
kono
parents:
diff changeset
488 Call : constant Node_Id := Expression (Expression (N));
kono
parents:
diff changeset
489 begin
kono
parents:
diff changeset
490 Setup_Asm_IO_Args
kono
parents:
diff changeset
491 (Next_Actual (First_Actual (Call)),
kono
parents:
diff changeset
492 Current_Output_Operand);
kono
parents:
diff changeset
493 end Setup_Asm_Outputs;
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 end Exp_Code;