1 | /* Bytecode conversion definitions for GNU C-compiler. |
---|
2 | Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc. |
---|
3 | |
---|
4 | This file is part of GNU CC. |
---|
5 | |
---|
6 | GNU CC is free software; you can redistribute it and/or modify |
---|
7 | it under the terms of the GNU General Public License as published by |
---|
8 | the Free Software Foundation; either version 2, or (at your option) |
---|
9 | any later version. |
---|
10 | |
---|
11 | GNU CC is distributed in the hope that it will be useful, |
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | GNU General Public License for more details. |
---|
15 | |
---|
16 | You should have received a copy of the GNU General Public License |
---|
17 | along with GNU CC; see the file COPYING. If not, write to |
---|
18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
---|
19 | Boston, MA 02111-1307, USA. */ |
---|
20 | |
---|
21 | |
---|
22 | #include "config.h" |
---|
23 | #include <stdio.h> |
---|
24 | #ifdef HAVE_STDLIB_H |
---|
25 | #include <stdlib.h> |
---|
26 | #endif |
---|
27 | #include "tree.h" |
---|
28 | #include "rtl.h" |
---|
29 | #include "machmode.h" |
---|
30 | #include "obstack.h" |
---|
31 | #include "bytecode.h" |
---|
32 | #include "bc-typecd.h" |
---|
33 | #include "bc-opcode.h" |
---|
34 | #include "bc-optab.h" |
---|
35 | |
---|
36 | #define obstack_chunk_alloc xmalloc |
---|
37 | #define obstack_chunk_free free |
---|
38 | |
---|
39 | extern char *xmalloc (); |
---|
40 | |
---|
41 | /* Table relating interpreter typecodes to machine modes. */ |
---|
42 | #define GET_TYPECODE_MODE(CODE) (typecode_mode[((int) CODE)]) |
---|
43 | enum machine_mode typecode_mode[] = { |
---|
44 | #define DEFTYPECODE(CODE, NAME, MODE, TYPE) MODE, |
---|
45 | #include "bc-typecd.def" |
---|
46 | #undef DEFTYPECODE |
---|
47 | }; |
---|
48 | |
---|
49 | /* Machine mode to type code map */ |
---|
50 | static enum typecode signed_mode_to_code_map[MAX_MACHINE_MODE+1]; |
---|
51 | static enum typecode unsigned_mode_to_code_map[MAX_MACHINE_MODE+1]; |
---|
52 | |
---|
53 | #define GET_TYPECODE_SIZE(CODE) GET_MODE_SIZE (GET_TYPECODE_MODE (CODE)) |
---|
54 | |
---|
55 | #define BIG_ARBITRARY_NUMBER 100000 |
---|
56 | |
---|
57 | /* Table of recipes for conversions among scalar types, to be filled |
---|
58 | in as needed at run time. */ |
---|
59 | static struct conversion_recipe |
---|
60 | { |
---|
61 | unsigned char *opcodes; /* Bytecodes to emit in order. */ |
---|
62 | int nopcodes; /* Count of bytecodes. */ |
---|
63 | int cost; /* A rather arbitrary cost function. */ |
---|
64 | } conversion_recipe[NUM_TYPECODES][NUM_TYPECODES]; |
---|
65 | |
---|
66 | /* Binary operator tables. */ |
---|
67 | struct binary_operator optab_plus_expr[] = { |
---|
68 | { addSI, SIcode, SIcode, SIcode }, |
---|
69 | { addDI, DIcode, DIcode, DIcode }, |
---|
70 | { addSF, SFcode, SFcode, SFcode }, |
---|
71 | { addDF, DFcode, DFcode, DFcode }, |
---|
72 | { addXF, XFcode, XFcode, XFcode }, |
---|
73 | { addPSI, Pcode, Pcode, SIcode }, |
---|
74 | { -1, -1, -1, -1 }, |
---|
75 | }; |
---|
76 | |
---|
77 | struct binary_operator optab_minus_expr[] = { |
---|
78 | { subSI, SIcode, SIcode, SIcode }, |
---|
79 | { subDI, DIcode, DIcode, DIcode }, |
---|
80 | { subSF, SFcode, SFcode, SFcode }, |
---|
81 | { subDF, DFcode, DFcode, DFcode }, |
---|
82 | { subXF, XFcode, XFcode, XFcode }, |
---|
83 | { subPP, SIcode, Pcode, Pcode }, |
---|
84 | { -1, -1, -1, -1 }, |
---|
85 | }; |
---|
86 | |
---|
87 | /* The ordering of the tables for multiplicative operators |
---|
88 | is such that unsigned operations will be preferred to signed |
---|
89 | operations when one argument is unsigned. */ |
---|
90 | |
---|
91 | struct binary_operator optab_mult_expr[] = { |
---|
92 | { mulSU, SUcode, SUcode, SUcode }, |
---|
93 | { mulDU, DUcode, DUcode, DUcode }, |
---|
94 | { mulSI, SIcode, SIcode, SIcode }, |
---|
95 | { mulDI, DIcode, DIcode, DIcode }, |
---|
96 | { mulSF, SFcode, SFcode, SFcode }, |
---|
97 | { mulDF, DFcode, DFcode, DFcode }, |
---|
98 | { mulXF, XFcode, XFcode, XFcode }, |
---|
99 | { -1, -1, -1, -1 }, |
---|
100 | }; |
---|
101 | |
---|
102 | struct binary_operator optab_trunc_div_expr[] = { |
---|
103 | { divSU, SUcode, SUcode, SUcode }, |
---|
104 | { divDU, DUcode, DUcode, DUcode }, |
---|
105 | { divSI, SIcode, SIcode, SIcode }, |
---|
106 | { divDI, DIcode, DIcode, DIcode }, |
---|
107 | { -1, -1, -1, -1 }, |
---|
108 | }; |
---|
109 | |
---|
110 | struct binary_operator optab_trunc_mod_expr[] = { |
---|
111 | { modSU, SUcode, SUcode, SUcode }, |
---|
112 | { modDU, DUcode, DUcode, DUcode }, |
---|
113 | { modSI, SIcode, SIcode, SIcode }, |
---|
114 | { modDI, DIcode, DIcode, DIcode }, |
---|
115 | { -1, -1, -1, -1 }, |
---|
116 | }; |
---|
117 | |
---|
118 | struct binary_operator optab_rdiv_expr[] = { |
---|
119 | { divSF, SFcode, SFcode, SFcode }, |
---|
120 | { divDF, DFcode, DFcode, DFcode }, |
---|
121 | { divXF, XFcode, XFcode, XFcode }, |
---|
122 | { -1, -1, -1, -1 }, |
---|
123 | }; |
---|
124 | |
---|
125 | struct binary_operator optab_bit_and_expr[] = { |
---|
126 | { andSI, SIcode, SIcode, SIcode }, |
---|
127 | { andDI, DIcode, DIcode, DIcode }, |
---|
128 | { -1, -1, -1, -1 }, |
---|
129 | }; |
---|
130 | |
---|
131 | struct binary_operator optab_bit_ior_expr[] = { |
---|
132 | { iorSI, SIcode, SIcode, SIcode }, |
---|
133 | { iorDI, DIcode, DIcode, DIcode }, |
---|
134 | { -1, -1, -1, -1 }, |
---|
135 | }; |
---|
136 | |
---|
137 | struct binary_operator optab_bit_xor_expr[] = { |
---|
138 | { xorSI, SIcode, SIcode, SIcode }, |
---|
139 | { xorDI, DIcode, DIcode, DIcode }, |
---|
140 | { -1, -1, -1, -1 }, |
---|
141 | }; |
---|
142 | |
---|
143 | struct binary_operator optab_lshift_expr[] = { |
---|
144 | { lshiftSI, SIcode, SIcode, SIcode }, |
---|
145 | { lshiftSU, SUcode, SUcode, SIcode }, |
---|
146 | { lshiftDI, DIcode, DIcode, SIcode }, |
---|
147 | { lshiftDU, DUcode, DUcode, SIcode }, |
---|
148 | { -1, -1, -1, -1 }, |
---|
149 | }; |
---|
150 | |
---|
151 | struct binary_operator optab_rshift_expr[] = { |
---|
152 | { rshiftSI, SIcode, SIcode, SIcode }, |
---|
153 | { rshiftSU, SUcode, SUcode, SIcode }, |
---|
154 | { rshiftDI, DIcode, DIcode, SIcode }, |
---|
155 | { rshiftDU, DUcode, DUcode, SIcode }, |
---|
156 | { -1, -1, -1, -1 }, |
---|
157 | }; |
---|
158 | |
---|
159 | struct binary_operator optab_truth_and_expr[] = { |
---|
160 | { andSI, SIcode, Tcode, Tcode }, |
---|
161 | { -1, -1, -1, -1 }, |
---|
162 | }; |
---|
163 | |
---|
164 | struct binary_operator optab_truth_or_expr[] = { |
---|
165 | { iorSI, SIcode, Tcode, Tcode }, |
---|
166 | { -1, -1, -1, -1 }, |
---|
167 | }; |
---|
168 | |
---|
169 | struct binary_operator optab_lt_expr[] = { |
---|
170 | { ltSI, Tcode, SIcode, SIcode }, |
---|
171 | { ltSU, Tcode, SUcode, SUcode }, |
---|
172 | { ltDI, Tcode, DIcode, DIcode }, |
---|
173 | { ltDU, Tcode, DUcode, DUcode }, |
---|
174 | { ltSF, Tcode, SFcode, SFcode }, |
---|
175 | { ltDF, Tcode, DFcode, DFcode }, |
---|
176 | { ltXF, Tcode, XFcode, XFcode }, |
---|
177 | { ltP, Tcode, Pcode, Pcode }, |
---|
178 | { -1, -1, -1, -1 }, |
---|
179 | }; |
---|
180 | |
---|
181 | struct binary_operator optab_le_expr[] = { |
---|
182 | { leSI, Tcode, SIcode, SIcode }, |
---|
183 | { leSU, Tcode, SUcode, SUcode }, |
---|
184 | { leDI, Tcode, DIcode, DIcode }, |
---|
185 | { leDU, Tcode, DUcode, DUcode }, |
---|
186 | { leSF, Tcode, SFcode, SFcode }, |
---|
187 | { leDF, Tcode, DFcode, DFcode }, |
---|
188 | { leXF, Tcode, XFcode, XFcode }, |
---|
189 | { leP, Tcode, Pcode, Pcode }, |
---|
190 | { -1, -1, -1, -1 }, |
---|
191 | }; |
---|
192 | |
---|
193 | struct binary_operator optab_ge_expr[] = { |
---|
194 | { geSI, Tcode, SIcode, SIcode }, |
---|
195 | { geSU, Tcode, SUcode, SUcode }, |
---|
196 | { geDI, Tcode, DIcode, DIcode }, |
---|
197 | { geDU, Tcode, DUcode, DUcode }, |
---|
198 | { geSF, Tcode, SFcode, SFcode }, |
---|
199 | { geDF, Tcode, DFcode, DFcode }, |
---|
200 | { geXF, Tcode, XFcode, XFcode }, |
---|
201 | { geP, Tcode, Pcode, Pcode }, |
---|
202 | { -1, -1, -1, -1 }, |
---|
203 | }; |
---|
204 | |
---|
205 | struct binary_operator optab_gt_expr[] = { |
---|
206 | { gtSI, Tcode, SIcode, SIcode }, |
---|
207 | { gtSU, Tcode, SUcode, SUcode }, |
---|
208 | { gtDI, Tcode, DIcode, DIcode }, |
---|
209 | { gtDU, Tcode, DUcode, DUcode }, |
---|
210 | { gtSF, Tcode, SFcode, SFcode }, |
---|
211 | { gtDF, Tcode, DFcode, DFcode }, |
---|
212 | { gtXF, Tcode, XFcode, XFcode }, |
---|
213 | { gtP, Tcode, Pcode, Pcode }, |
---|
214 | { -1, -1, -1, -1 }, |
---|
215 | }; |
---|
216 | |
---|
217 | struct binary_operator optab_eq_expr[] = { |
---|
218 | { eqSI, Tcode, SIcode, SIcode }, |
---|
219 | { eqDI, Tcode, DIcode, DIcode }, |
---|
220 | { eqSF, Tcode, SFcode, SFcode }, |
---|
221 | { eqDF, Tcode, DFcode, DFcode }, |
---|
222 | { eqXF, Tcode, XFcode, XFcode }, |
---|
223 | { eqP, Tcode, Pcode, Pcode }, |
---|
224 | { -1, -1, -1, -1 }, |
---|
225 | }; |
---|
226 | |
---|
227 | struct binary_operator optab_ne_expr[] = { |
---|
228 | { neSI, Tcode, SIcode, SIcode }, |
---|
229 | { neDI, Tcode, DIcode, DIcode }, |
---|
230 | { neSF, Tcode, SFcode, SFcode }, |
---|
231 | { neDF, Tcode, DFcode, DFcode }, |
---|
232 | { neXF, Tcode, XFcode, XFcode }, |
---|
233 | { neP, Tcode, Pcode, Pcode }, |
---|
234 | { -1, -1, -1, -1 }, |
---|
235 | }; |
---|
236 | |
---|
237 | /* Unary operator tables. */ |
---|
238 | struct unary_operator optab_negate_expr[] = { |
---|
239 | { negSI, SIcode, SIcode }, |
---|
240 | { negDI, DIcode, DIcode }, |
---|
241 | { negSF, SFcode, SFcode }, |
---|
242 | { negDF, DFcode, DFcode }, |
---|
243 | { negXF, XFcode, XFcode }, |
---|
244 | { -1, -1, -1 }, |
---|
245 | }; |
---|
246 | |
---|
247 | struct unary_operator optab_bit_not_expr[] = { |
---|
248 | { notSI, SIcode, SIcode }, |
---|
249 | { notDI, DIcode, DIcode }, |
---|
250 | { -1, -1, -1 }, |
---|
251 | }; |
---|
252 | |
---|
253 | struct unary_operator optab_truth_not_expr[] = { |
---|
254 | { notT, SIcode, SIcode }, |
---|
255 | { -1, -1, -1 }, |
---|
256 | }; |
---|
257 | |
---|
258 | /* Increment operator tables. */ |
---|
259 | struct increment_operator optab_predecrement_expr[] = { |
---|
260 | { predecQI, QIcode }, |
---|
261 | { predecQI, QUcode }, |
---|
262 | { predecHI, HIcode }, |
---|
263 | { predecHI, HUcode }, |
---|
264 | { predecSI, SIcode }, |
---|
265 | { predecSI, SUcode }, |
---|
266 | { predecDI, DIcode }, |
---|
267 | { predecDI, DUcode }, |
---|
268 | { predecP, Pcode }, |
---|
269 | { predecSF, SFcode }, |
---|
270 | { predecDF, DFcode }, |
---|
271 | { predecXF, XFcode }, |
---|
272 | { -1, -1 }, |
---|
273 | }; |
---|
274 | |
---|
275 | struct increment_operator optab_preincrement_expr[] = { |
---|
276 | { preincQI, QIcode }, |
---|
277 | { preincQI, QUcode }, |
---|
278 | { preincHI, HIcode }, |
---|
279 | { preincHI, HUcode }, |
---|
280 | { preincSI, SIcode }, |
---|
281 | { preincSI, SUcode }, |
---|
282 | { preincDI, DIcode }, |
---|
283 | { preincDI, DUcode }, |
---|
284 | { preincP, Pcode }, |
---|
285 | { preincSF, SFcode }, |
---|
286 | { preincDF, DFcode }, |
---|
287 | { preincXF, XFcode }, |
---|
288 | { -1, -1 }, |
---|
289 | }; |
---|
290 | |
---|
291 | struct increment_operator optab_postdecrement_expr[] = { |
---|
292 | { postdecQI, QIcode }, |
---|
293 | { postdecQI, QUcode }, |
---|
294 | { postdecHI, HIcode }, |
---|
295 | { postdecHI, HUcode }, |
---|
296 | { postdecSI, SIcode }, |
---|
297 | { postdecSI, SUcode }, |
---|
298 | { postdecDI, DIcode }, |
---|
299 | { postdecDI, DUcode }, |
---|
300 | { postdecP, Pcode }, |
---|
301 | { postdecSF, SFcode }, |
---|
302 | { postdecDF, DFcode }, |
---|
303 | { postdecXF, XFcode }, |
---|
304 | { -1, -1 }, |
---|
305 | }; |
---|
306 | |
---|
307 | struct increment_operator optab_postincrement_expr[] = { |
---|
308 | { postincQI, QIcode }, |
---|
309 | { postincQI, QUcode }, |
---|
310 | { postincHI, HIcode }, |
---|
311 | { postincHI, HUcode }, |
---|
312 | { postincSI, SIcode }, |
---|
313 | { postincSI, SUcode }, |
---|
314 | { postincDI, DIcode }, |
---|
315 | { postincDI, DUcode }, |
---|
316 | { postincP, Pcode }, |
---|
317 | { postincSF, SFcode }, |
---|
318 | { postincDF, DFcode }, |
---|
319 | { postincXF, XFcode }, |
---|
320 | { -1, -1 }, |
---|
321 | }; |
---|
322 | |
---|
323 | /* Table of conversions supported by the interpreter. */ |
---|
324 | static struct conversion_info |
---|
325 | { |
---|
326 | enum bytecode_opcode opcode; /* here indicates the conversion needs no opcode. */ |
---|
327 | enum typecode from; |
---|
328 | enum typecode to; |
---|
329 | int cost; /* 1 for no-op conversions, 2 for widening conversions, |
---|
330 | 4 for int/float conversions, 8 for narrowing conversions. */ |
---|
331 | } conversion_info[] = { |
---|
332 | { -1, QIcode, QUcode, 1 }, |
---|
333 | { -1, HIcode, HUcode, 1 }, |
---|
334 | { -1, SIcode, SUcode, 1 }, |
---|
335 | { -1, DIcode, DUcode, 1 }, |
---|
336 | { -1, QUcode, QIcode, 1 }, |
---|
337 | { -1, HUcode, HIcode, 1 }, |
---|
338 | { -1, SUcode, SIcode, 1 }, |
---|
339 | { -1, DUcode, DIcode, 1 }, |
---|
340 | { -1, Tcode, SIcode, 1 }, |
---|
341 | { convertQIHI, QIcode, HIcode, 2 }, |
---|
342 | { convertQUHU, QUcode, HUcode, 2 }, |
---|
343 | { convertQUSU, QUcode, SUcode, 2 }, |
---|
344 | { convertHISI, HIcode, SIcode, 2 }, |
---|
345 | { convertHUSU, HUcode, SUcode, 2 }, |
---|
346 | { convertSIDI, SIcode, DIcode, 2 }, |
---|
347 | { convertSUDU, SUcode, DUcode, 2 }, |
---|
348 | { convertSFDF, SFcode, DFcode, 2 }, |
---|
349 | { convertDFXF, DFcode, XFcode, 2 }, |
---|
350 | { convertHIQI, HIcode, QIcode, 8 }, |
---|
351 | { convertSIQI, SIcode, QIcode, 8 }, |
---|
352 | { convertSIHI, SIcode, HIcode, 8 }, |
---|
353 | { convertSUQU, SUcode, QUcode, 8 }, |
---|
354 | { convertDISI, DIcode, SIcode, 8 }, |
---|
355 | { convertDFSF, DFcode, SFcode, 8 }, |
---|
356 | { convertXFDF, XFcode, DFcode, 8 }, |
---|
357 | { convertPSI, Pcode, SIcode, 2 }, |
---|
358 | { convertSIP, SIcode, Pcode, 2 }, |
---|
359 | { convertSIT, SIcode, Tcode, 2 }, |
---|
360 | { convertDIT, DIcode, Tcode, 2 }, |
---|
361 | { convertSFT, SFcode, Tcode, 2 }, |
---|
362 | { convertDFT, DFcode, Tcode, 2 }, |
---|
363 | { convertXFT, XFcode, Tcode, 2 }, |
---|
364 | { convertQISI, QIcode, SIcode, 2 }, |
---|
365 | { convertPT, Pcode, Tcode, 2 }, |
---|
366 | { convertSISF, SIcode, SFcode, 4 }, |
---|
367 | { convertSIDF, SIcode, DFcode, 4 }, |
---|
368 | { convertSIXF, SIcode, XFcode, 4 }, |
---|
369 | { convertSUSF, SUcode, SFcode, 4 }, |
---|
370 | { convertSUDF, SUcode, DFcode, 4 }, |
---|
371 | { convertSUXF, SUcode, XFcode, 4 }, |
---|
372 | { convertDISF, DIcode, SFcode, 4 }, |
---|
373 | { convertDIDF, DIcode, DFcode, 4 }, |
---|
374 | { convertDIXF, DIcode, XFcode, 4 }, |
---|
375 | { convertDUSF, DUcode, SFcode, 4 }, |
---|
376 | { convertDUDF, DUcode, DFcode, 4 }, |
---|
377 | { convertDUXF, DUcode, XFcode, 4 }, |
---|
378 | { convertSFSI, SFcode, SIcode, 4 }, |
---|
379 | { convertDFSI, DFcode, SIcode, 4 }, |
---|
380 | { convertXFSI, XFcode, SIcode, 4 }, |
---|
381 | { convertSFSU, SFcode, SUcode, 4 }, |
---|
382 | { convertDFSU, DFcode, SUcode, 4 }, |
---|
383 | { convertXFSU, XFcode, SUcode, 4 }, |
---|
384 | { convertSFDI, SFcode, DIcode, 4 }, |
---|
385 | { convertDFDI, DFcode, DIcode, 4 }, |
---|
386 | { convertXFDI, XFcode, DIcode, 4 }, |
---|
387 | { convertSFDU, SFcode, DUcode, 4 }, |
---|
388 | { convertDFDU, DFcode, DUcode, 4 }, |
---|
389 | { convertXFDU, XFcode, DUcode, 4 }, |
---|
390 | { convertSIQI, SIcode, QIcode, 8 }, |
---|
391 | }; |
---|
392 | |
---|
393 | #define NUM_CONVERSIONS (sizeof conversion_info / sizeof (struct conversion_info)) |
---|
394 | |
---|
395 | /* List form of a conversion recipe. */ |
---|
396 | struct conversion_list |
---|
397 | { |
---|
398 | enum bytecode_opcode opcode; |
---|
399 | enum typecode to; |
---|
400 | int cost; |
---|
401 | struct conversion_list *prev; |
---|
402 | }; |
---|
403 | |
---|
404 | /* Determine if it is "reasonable" to add a given conversion to |
---|
405 | a given list of conversions. The following criteria define |
---|
406 | "reasonable" conversion lists: |
---|
407 | * No typecode appears more than once in the sequence (no loops). |
---|
408 | * At most one conversion from integer to float or vice versa is present. |
---|
409 | * Either sign extensions or zero extensions may be present, but not both. |
---|
410 | * No widening conversions occur after a signed/unsigned conversion. |
---|
411 | * The sequence of sizes must be strict nonincreasing or nondecreasing. */ |
---|
412 | |
---|
413 | static int |
---|
414 | conversion_reasonable_p (conversion, list) |
---|
415 | struct conversion_info *conversion; |
---|
416 | struct conversion_list *list; |
---|
417 | { |
---|
418 | struct conversion_list *curr; |
---|
419 | int curr_size, prev_size; |
---|
420 | int has_int_float, has_float_int; |
---|
421 | int has_sign_extend, has_zero_extend; |
---|
422 | int has_signed_unsigned, has_unsigned_signed; |
---|
423 | |
---|
424 | has_int_float = 0; |
---|
425 | has_float_int = 0; |
---|
426 | has_sign_extend = 0; |
---|
427 | has_zero_extend = 0; |
---|
428 | has_signed_unsigned = 0; |
---|
429 | has_unsigned_signed = 0; |
---|
430 | |
---|
431 | /* Make sure the destination typecode doesn't already appear in |
---|
432 | the list. */ |
---|
433 | for (curr = list; curr; curr = curr->prev) |
---|
434 | if (conversion->to == curr->to) |
---|
435 | return 0; |
---|
436 | |
---|
437 | /* Check for certain kinds of conversions. */ |
---|
438 | if (TYPECODE_INTEGER_P (conversion->from) |
---|
439 | && TYPECODE_FLOAT_P (conversion->to)) |
---|
440 | has_int_float = 1; |
---|
441 | if (TYPECODE_FLOAT_P (conversion->from) |
---|
442 | && TYPECODE_INTEGER_P (conversion->to)) |
---|
443 | has_float_int = 1; |
---|
444 | if (TYPECODE_SIGNED_P (conversion->from) |
---|
445 | && TYPECODE_SIGNED_P (conversion->to) |
---|
446 | && GET_TYPECODE_SIZE (conversion->from) |
---|
447 | < GET_TYPECODE_SIZE (conversion->to)) |
---|
448 | has_sign_extend = 1; |
---|
449 | if (TYPECODE_UNSIGNED_P (conversion->from) |
---|
450 | && TYPECODE_UNSIGNED_P (conversion->to) |
---|
451 | && GET_TYPECODE_SIZE (conversion->from) |
---|
452 | < GET_TYPECODE_SIZE (conversion->to)) |
---|
453 | has_zero_extend = 1; |
---|
454 | |
---|
455 | for (curr = list; curr && curr->prev; curr = curr->prev) |
---|
456 | { |
---|
457 | if (TYPECODE_INTEGER_P (curr->prev->to) |
---|
458 | && TYPECODE_FLOAT_P (curr->to)) |
---|
459 | has_int_float = 1; |
---|
460 | if (TYPECODE_FLOAT_P (curr->prev->to) |
---|
461 | && TYPECODE_INTEGER_P (curr->to)) |
---|
462 | has_float_int = 1; |
---|
463 | if (TYPECODE_SIGNED_P (curr->prev->to) |
---|
464 | && TYPECODE_SIGNED_P (curr->to) |
---|
465 | && GET_TYPECODE_SIZE (curr->prev->to) |
---|
466 | < GET_TYPECODE_SIZE (curr->to)) |
---|
467 | has_sign_extend = 1; |
---|
468 | if (TYPECODE_UNSIGNED_P (curr->prev->to) |
---|
469 | && TYPECODE_UNSIGNED_P (curr->to) |
---|
470 | && GET_TYPECODE_SIZE (curr->prev->to) |
---|
471 | < GET_TYPECODE_SIZE (curr->to)) |
---|
472 | has_zero_extend = 1; |
---|
473 | if (TYPECODE_SIGNED_P (curr->prev->to) |
---|
474 | && TYPECODE_UNSIGNED_P (curr->to)) |
---|
475 | has_signed_unsigned = 1; |
---|
476 | if (TYPECODE_UNSIGNED_P (curr->prev->to) |
---|
477 | && TYPECODE_SIGNED_P (curr->to)) |
---|
478 | has_unsigned_signed = 1; |
---|
479 | } |
---|
480 | |
---|
481 | if (TYPECODE_INTEGER_P (conversion->from) |
---|
482 | && TYPECODE_INTEGER_P (conversion->to) |
---|
483 | && GET_TYPECODE_SIZE (conversion->to) |
---|
484 | > GET_TYPECODE_SIZE (conversion->from) |
---|
485 | && (has_signed_unsigned || has_unsigned_signed)) |
---|
486 | return 0; |
---|
487 | |
---|
488 | if (has_float_int && has_int_float || has_sign_extend && has_zero_extend) |
---|
489 | return 0; |
---|
490 | |
---|
491 | /* Make sure the sequence of destination typecode sizes is |
---|
492 | strictly nondecreasing or strictly nonincreasing. */ |
---|
493 | prev_size = GET_TYPECODE_SIZE (conversion->to); |
---|
494 | for (curr = list; curr; curr = curr->prev) |
---|
495 | { |
---|
496 | curr_size = GET_TYPECODE_SIZE (curr->to); |
---|
497 | if (curr_size != prev_size) |
---|
498 | break; |
---|
499 | } |
---|
500 | if (!curr) |
---|
501 | return 1; |
---|
502 | |
---|
503 | if (curr_size < prev_size) |
---|
504 | for (prev_size = curr_size; curr; curr = curr->prev) |
---|
505 | { |
---|
506 | curr_size = GET_TYPECODE_SIZE (curr->to); |
---|
507 | if (curr_size > prev_size) |
---|
508 | return 0; |
---|
509 | prev_size = curr_size; |
---|
510 | } |
---|
511 | else |
---|
512 | for (prev_size = curr_size; curr; curr = curr->prev) |
---|
513 | { |
---|
514 | curr_size = GET_TYPECODE_SIZE (curr->to); |
---|
515 | if (curr_size < prev_size) |
---|
516 | return 0; |
---|
517 | prev_size = curr_size; |
---|
518 | } |
---|
519 | return 1; |
---|
520 | } |
---|
521 | |
---|
522 | |
---|
523 | /* Exhaustively search all reasonable conversions to find one to |
---|
524 | convert the given types. */ |
---|
525 | |
---|
526 | static struct conversion_recipe |
---|
527 | deduce_conversion (from, to) |
---|
528 | enum typecode from, to; |
---|
529 | { |
---|
530 | struct rl |
---|
531 | { |
---|
532 | struct conversion_list *list; |
---|
533 | struct rl *next; |
---|
534 | } *prev, curr, *good, *temp; |
---|
535 | struct conversion_list *conv, *best; |
---|
536 | int i, cost, bestcost; |
---|
537 | struct conversion_recipe result; |
---|
538 | struct obstack recipe_obstack; |
---|
539 | |
---|
540 | |
---|
541 | obstack_init (&recipe_obstack); |
---|
542 | curr.next = (struct rl *) obstack_alloc (&recipe_obstack, sizeof (struct rl)); |
---|
543 | curr.next->list |
---|
544 | = (struct conversion_list *) obstack_alloc (&recipe_obstack, |
---|
545 | sizeof (struct conversion_list)); |
---|
546 | curr.next->list->opcode = -1; |
---|
547 | curr.next->list->to = from; |
---|
548 | curr.next->list->cost = 0; |
---|
549 | curr.next->list->prev = 0; |
---|
550 | curr.next->next = 0; |
---|
551 | good = 0; |
---|
552 | |
---|
553 | while (curr.next) |
---|
554 | { |
---|
555 | /* Remove successful conversions from further consideration. */ |
---|
556 | for (prev = &curr; prev; prev = prev->next) |
---|
557 | if (prev->next && prev->next->list->to == to) |
---|
558 | { |
---|
559 | temp = prev->next->next; |
---|
560 | prev->next->next = good; |
---|
561 | good = prev->next; |
---|
562 | prev->next = temp; |
---|
563 | } |
---|
564 | |
---|
565 | /* Go through each of the pending conversion chains, trying |
---|
566 | all possible candidate conversions on them. */ |
---|
567 | for (prev = curr.next, curr.next = 0; prev; prev = prev->next) |
---|
568 | for (i = 0; i < NUM_CONVERSIONS; ++i) |
---|
569 | if (conversion_info[i].from == prev->list->to |
---|
570 | && conversion_reasonable_p (&conversion_info[i], prev->list)) |
---|
571 | { |
---|
572 | temp = (struct rl *) obstack_alloc (&recipe_obstack, |
---|
573 | sizeof (struct rl)); |
---|
574 | temp->list = (struct conversion_list *) |
---|
575 | obstack_alloc (&recipe_obstack, |
---|
576 | sizeof (struct conversion_list)); |
---|
577 | temp->list->opcode = conversion_info[i].opcode; |
---|
578 | temp->list->to = conversion_info[i].to; |
---|
579 | temp->list->cost = conversion_info[i].cost; |
---|
580 | temp->list->prev = prev->list; |
---|
581 | temp->next = curr.next; |
---|
582 | curr.next = temp; |
---|
583 | } |
---|
584 | } |
---|
585 | |
---|
586 | bestcost = BIG_ARBITRARY_NUMBER; |
---|
587 | best = 0; |
---|
588 | for (temp = good; temp; temp = temp->next) |
---|
589 | { |
---|
590 | for (conv = temp->list, cost = 0; conv; conv = conv->prev) |
---|
591 | cost += conv->cost; |
---|
592 | if (cost < bestcost) |
---|
593 | { |
---|
594 | bestcost = cost; |
---|
595 | best = temp->list; |
---|
596 | } |
---|
597 | } |
---|
598 | |
---|
599 | if (!best) |
---|
600 | abort (); |
---|
601 | |
---|
602 | for (i = 0, conv = best; conv; conv = conv->prev) |
---|
603 | if (conv->opcode != -1) |
---|
604 | ++i; |
---|
605 | |
---|
606 | result.opcodes = (unsigned char *) xmalloc (i); |
---|
607 | result.nopcodes = i; |
---|
608 | for (conv = best; conv; conv = conv->prev) |
---|
609 | if (conv->opcode != -1) |
---|
610 | result.opcodes[--i] = conv->opcode; |
---|
611 | result.cost = bestcost; |
---|
612 | obstack_free (&recipe_obstack, 0); |
---|
613 | return result; |
---|
614 | } |
---|
615 | |
---|
616 | #define DEDUCE_CONVERSION(FROM, TO) \ |
---|
617 | (conversion_recipe[(int) FROM][(int) TO].opcodes ? 0 \ |
---|
618 | : (conversion_recipe[(int) FROM][(int) TO] \ |
---|
619 | = deduce_conversion (FROM, TO), 0)) |
---|
620 | |
---|
621 | |
---|
622 | /* Emit a conversion between the given scalar types. */ |
---|
623 | |
---|
624 | void |
---|
625 | emit_typecode_conversion (from, to) |
---|
626 | enum typecode from, to; |
---|
627 | { |
---|
628 | int i; |
---|
629 | |
---|
630 | DEDUCE_CONVERSION (from, to); |
---|
631 | for (i = 0; i < conversion_recipe[(int) from][(int) to].nopcodes; ++i) |
---|
632 | bc_emit_instruction (conversion_recipe[(int) from][(int) to].opcodes[i]); |
---|
633 | } |
---|
634 | |
---|
635 | |
---|
636 | /* Initialize mode_to_code_map[] */ |
---|
637 | |
---|
638 | void |
---|
639 | bc_init_mode_to_code_map () |
---|
640 | { |
---|
641 | int mode; |
---|
642 | |
---|
643 | for (mode = 0; mode < MAX_MACHINE_MODE + 1; mode++) |
---|
644 | { |
---|
645 | signed_mode_to_code_map[mode] |
---|
646 | = unsigned_mode_to_code_map[mode] |
---|
647 | = LAST_AND_UNUSED_TYPECODE; |
---|
648 | } |
---|
649 | |
---|
650 | #define DEF_MODEMAP(SYM, CODE, UCODE, CONST, LOAD, STORE) \ |
---|
651 | { signed_mode_to_code_map[(int) SYM] = CODE; \ |
---|
652 | unsigned_mode_to_code_map[(int) SYM] = UCODE; } |
---|
653 | #include "modemap.def" |
---|
654 | #undef DEF_MODEMAP |
---|
655 | |
---|
656 | /* Initialize opcode maps for const, load, and store */ |
---|
657 | bc_init_mode_to_opcode_maps (); |
---|
658 | } |
---|
659 | |
---|
660 | /* Given a machine mode return the preferred typecode. */ |
---|
661 | |
---|
662 | enum typecode |
---|
663 | preferred_typecode (mode, unsignedp) |
---|
664 | enum machine_mode mode; |
---|
665 | int unsignedp; |
---|
666 | { |
---|
667 | enum typecode code = (unsignedp |
---|
668 | ? unsigned_mode_to_code_map |
---|
669 | : signed_mode_to_code_map) [MIN ((int) mode, |
---|
670 | (int) MAX_MACHINE_MODE)]; |
---|
671 | |
---|
672 | if (code == LAST_AND_UNUSED_TYPECODE) |
---|
673 | abort (); |
---|
674 | |
---|
675 | return code; |
---|
676 | } |
---|
677 | |
---|
678 | |
---|
679 | /* Expand a conversion between the given types. */ |
---|
680 | |
---|
681 | void |
---|
682 | bc_expand_conversion (from, to) |
---|
683 | tree from, to; |
---|
684 | { |
---|
685 | enum typecode fcode, tcode; |
---|
686 | |
---|
687 | fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from)); |
---|
688 | tcode = preferred_typecode (TYPE_MODE (to), TREE_UNSIGNED (to)); |
---|
689 | |
---|
690 | emit_typecode_conversion (fcode, tcode); |
---|
691 | } |
---|
692 | |
---|
693 | /* Expand a conversion of the given type to a truth value. */ |
---|
694 | |
---|
695 | void |
---|
696 | bc_expand_truth_conversion (from) |
---|
697 | tree from; |
---|
698 | { |
---|
699 | enum typecode fcode; |
---|
700 | |
---|
701 | fcode = preferred_typecode (TYPE_MODE (from), TREE_UNSIGNED (from)); |
---|
702 | emit_typecode_conversion (fcode, Tcode); |
---|
703 | } |
---|
704 | |
---|
705 | /* Emit an appropriate binary operation. */ |
---|
706 | |
---|
707 | void |
---|
708 | bc_expand_binary_operation (optab, resulttype, arg0, arg1) |
---|
709 | struct binary_operator optab[]; |
---|
710 | tree resulttype, arg0, arg1; |
---|
711 | { |
---|
712 | int i, besti, cost, bestcost; |
---|
713 | enum typecode resultcode, arg0code, arg1code; |
---|
714 | |
---|
715 | resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype)); |
---|
716 | arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (resulttype)); |
---|
717 | arg1code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg1)), TREE_UNSIGNED (resulttype)); |
---|
718 | |
---|
719 | besti = -1; |
---|
720 | bestcost = BIG_ARBITRARY_NUMBER; |
---|
721 | |
---|
722 | for (i = 0; optab[i].opcode != -1; ++i) |
---|
723 | { |
---|
724 | cost = 0; |
---|
725 | DEDUCE_CONVERSION (arg0code, optab[i].arg0); |
---|
726 | cost += conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost; |
---|
727 | DEDUCE_CONVERSION (arg1code, optab[i].arg1); |
---|
728 | cost += conversion_recipe[(int) arg1code][(int) optab[i].arg1].cost; |
---|
729 | if (cost < bestcost) |
---|
730 | { |
---|
731 | besti = i; |
---|
732 | bestcost = cost; |
---|
733 | } |
---|
734 | } |
---|
735 | |
---|
736 | if (besti == -1) |
---|
737 | abort (); |
---|
738 | |
---|
739 | expand_expr (arg1, 0, VOIDmode, 0); |
---|
740 | emit_typecode_conversion (arg1code, optab[besti].arg1); |
---|
741 | expand_expr (arg0, 0, VOIDmode, 0); |
---|
742 | emit_typecode_conversion (arg0code, optab[besti].arg0); |
---|
743 | bc_emit_instruction (optab[besti].opcode); |
---|
744 | emit_typecode_conversion (optab[besti].result, resultcode); |
---|
745 | } |
---|
746 | |
---|
747 | /* Emit an appropriate unary operation. */ |
---|
748 | |
---|
749 | void |
---|
750 | bc_expand_unary_operation (optab, resulttype, arg0) |
---|
751 | struct unary_operator optab[]; |
---|
752 | tree resulttype, arg0; |
---|
753 | { |
---|
754 | int i, besti, cost, bestcost; |
---|
755 | enum typecode resultcode, arg0code; |
---|
756 | |
---|
757 | resultcode = preferred_typecode (TYPE_MODE (resulttype), TREE_UNSIGNED (resulttype)); |
---|
758 | arg0code = preferred_typecode (TYPE_MODE (TREE_TYPE (arg0)), TREE_UNSIGNED (TREE_TYPE (arg0))); |
---|
759 | |
---|
760 | besti = -1; |
---|
761 | bestcost = BIG_ARBITRARY_NUMBER; |
---|
762 | |
---|
763 | for (i = 0; optab[i].opcode != -1; ++i) |
---|
764 | { |
---|
765 | DEDUCE_CONVERSION (arg0code, optab[i].arg0); |
---|
766 | cost = conversion_recipe[(int) arg0code][(int) optab[i].arg0].cost; |
---|
767 | if (cost < bestcost) |
---|
768 | { |
---|
769 | besti = i; |
---|
770 | bestcost = cost; |
---|
771 | } |
---|
772 | } |
---|
773 | |
---|
774 | if (besti == -1) |
---|
775 | abort (); |
---|
776 | |
---|
777 | expand_expr (arg0, 0, VOIDmode, 0); |
---|
778 | emit_typecode_conversion (arg0code, optab[besti].arg0); |
---|
779 | bc_emit_instruction (optab[besti].opcode); |
---|
780 | emit_typecode_conversion (optab[besti].result, resultcode); |
---|
781 | } |
---|
782 | |
---|
783 | |
---|
784 | /* Emit an appropriate increment. */ |
---|
785 | |
---|
786 | void |
---|
787 | bc_expand_increment (optab, type) |
---|
788 | struct increment_operator optab[]; |
---|
789 | tree type; |
---|
790 | { |
---|
791 | enum typecode code; |
---|
792 | int i; |
---|
793 | |
---|
794 | code = preferred_typecode (TYPE_MODE (type), TREE_UNSIGNED (type)); |
---|
795 | for (i = 0; (int) optab[i].opcode >= 0; ++i) |
---|
796 | if (code == optab[i].arg) |
---|
797 | { |
---|
798 | bc_emit_instruction (optab[i].opcode); |
---|
799 | return; |
---|
800 | } |
---|
801 | abort (); |
---|
802 | } |
---|