OSDN Git Service

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